Index: ObsoleteFiles.inc =================================================================== --- ObsoleteFiles.inc +++ ObsoleteFiles.inc @@ -38,6 +38,17 @@ # xargs -n1 | sort | uniq -d; # done +# ????????: Remove floppy drive support +OLD_FILES+=usr/sbin/fdcontrol +OLD_FILES+=usr/sbin/fdformat +OLD_FILES+=usr/sbin/fdread +OLD_FILES+=usr/sbin/fdwrite +OLD_FILES+=usr/share/man/man1/fdformat.1.gz +OLD_FILES+=usr/share/man/man1/fdread.1.gz +OLD_FILES+=usr/share/man/man1/fdwrite.1.gz +OLD_FILES+=usr/share/man/man8/fdcontrol.8.gz +OLD_FILES+=etc/disktab + # 20171203: libproc version bump OLD_LIBS+=usr/lib/libproc.so.4 OLD_LIBS+=usr/lib32/libproc.so.4 Index: etc/disktab =================================================================== --- etc/disktab +++ /dev/null @@ -1,204 +0,0 @@ -# $FreeBSD$ -# -# Disk geometry and partition layout tables. -# See disktab(5) for format of this file. -# - -# -# Floppy formats: -# -# To make a filesystem on a floppy: -# fdformat [-f ] fd[.] -# disklabel -B -r -w fd[.] fd -# newfs fd[.] -# -# with : -# -t 2 - two heads -# -u 9|15|18 - sectors per track -# (using the default value of 1/4096 is not much useful for floppies) -# -l 1 - interleave 1 (for most floppies) -# -i 65536 - bytes of data per i-node -# (the default -i value will render you with a floppy wasting way -# too much space in i-node areas) -# - -fd360:\ - :ty=floppy:se#512:nt#2:rm#300:ns#9:nc#40:\ - :pa#720:oa#0:ba#4096:fa#512:\ - :pc#720:oc#0:bc#4096:fc#512: - -fd720:\ - :ty=floppy:se#512:nt#2:rm#300:ns#9:nc#80:\ - :pa#1440:oa#0:ba#4096:fa#512:\ - :pc#1440:oc#0:bc#4096:fc#512: - -fd1200|floppy5|5in|5.25in High Density Floppy:\ - :ty=floppy:se#512:nt#2:rm#360:ns#15:nc#80:\ - :pa#2400:oa#0:ba#4096:fa#512:\ - :pc#2400:oc#0:bc#4096:fc#512: - -fd1440|floppy|floppy3|3in|3.5in High Density Floppy:\ - :ty=floppy:se#512:nt#2:rm#300:ns#18:nc#80:\ - :pa#2880:oa#0:ba#4096:fa#512:\ - :pc#2880:oc#0:bc#4096:fc#512: - -fd2880|2.88MB 3.5in Extra High Density Floppy:\ - :ty=floppy:se#512:nt#2:rm#300:ns#36:nc#80:\ - :pa#5760:oa#0:ba#4096:fa#512:\ - :pb#5760:ob#0:bb#4096:fa#512:\ - :pc#5760:oc#0:bb#4096:fa#512: - -# -# Stressed floppy-formats. No guarantees given. -# - -fd800:\ - :ty=floppy:se#512:nt#2:rm#300:ns#10:nc#80:\ - :pa#1600:oa#0:ba#4096:fa#512:\ - :pc#1600:oc#0:bc#4096:fc#512: - -fd820:\ - :ty=floppy:se#512:nt#2:rm#300:ns#10:nc#82:\ - :pa#1640:oa#0:ba#4096:fa#512:\ - :pc#1640:oc#0:bc#4096:fc#512: - -fd1480:\ - :ty=floppy:se#512:nt#2:rm#300:ns#18:nc#82:\ - :pa#2952:oa#0:ba#4096:fa#512:\ - :pc#2952:oc#0:bc#4096:fc#512: - -fd1720:\ - :ty=floppy:se#512:nt#2:rm#300:ns#21:nc#82:\ - :pa#3444:oa#0:ba#4096:fa#512:\ - :pc#3444:oc#0:bc#4096:fc#512: - -# -# LS-120 floppy-format. -# -fd120m|floppy120|floppy120m|3.5in LS-120 Floppy:\ - :ty=floppy:se#512:nt#8:rm#300:ns#32:nc#963:\ - :pa#246528:oa#0:ba#4096:fa#512:\ - :pc#246528:oc#0:bc#4096:fc#512: - -# -# Harddisk formats -# -qp120at|Quantum Peripherals 120MB IDE:\ - :dt=ESDI:ty=winchester:se#512:nt#9:ns#32:nc#813:sf: \ - :pa#13824:oa#0:ta=4.2BSD:ba#4096:fa#512: \ - :pb#13824:ob#13824:tb=swap: \ - :pc#234144:oc#0: \ - :ph#206496:oh#27648:th=4.2BSD:bh#4096:fh#512: - -pan60|Panasonic Laptop's 60MB IDE:\ - :dt=ST506:ty=winchester:se#512:nt#13:ns#17:nc#565:\ - :pa#13260:oa#0:ta=4.2BSD:ba#4096:fa#512:\ - :pb#13260:ob#13260:tb=swap: \ - :pc#124865:oc#0: \ - :ph#97682:oh#26520:th=4.2BSD:bh#4096:fh#512: - -mk156|toshiba156|Toshiba MK156 156Mb:\ - :dt=SCSI:ty=winchester:se#512:nt#10:ns#35:nc#825:\ - :pa#15748:oa#0:ba#4096:fa#512:ta=4.2BSD:\ - :pb#15748:ob#15748:tb=swap:\ - :pc#288750:oc#0:\ - :ph#257250:oh#31500:bh#4096:fh#512:th=4.2BSD: - -cp3100|Connor Peripherals 100MB IDE:\ - :dt=ST506:ty=winchester:se#512:nt#8:ns#33:nc#766: \ - :pa#12144:oa#0:ta=4.2BSD:ba#4096:fa#512: \ - :pb#12144:ob#12144:tb=swap: \ - :pc#202224:oc#0: \ - :ph#177936:oh#24288:th=4.2BSD:bh#4096:fh#512: - -# a == root -# b == swap -# c == d == whole disk -# e == /var -# f == scratch -# h == /usr - -cp3100new|Connor Peripherals 100MB IDE, with a different configuration:\ - :dt=ST506:ty=winchester:se#512:nt#8:ns#33:nc#766: \ - :pa#15840:oa#0:ta=4.2BSD:ba#4096:fa#512: \ - :pb#24288:ob#15840:tb=swap: \ - :pc#202224:oc#0: \ - :pd#202224:od#0: \ - :pe#15840:oe#40128:te=4.2BSD:be#4096:fe#512: \ - :pg#15840:og#55968:tg=4.2BSD:bg#4096:fg#512: \ - :ph#130416:oh#71808:th=4.2BSD:bh#4096:fh#512: - -maxtor4380|Maxtor XT4380E ESDI :\ - :dt=ESDI:ty=winchester:se#512:nt#15:ns#36:nc#1222:sf: \ - :pa#21600:oa#0:ta=4.2BSD:ba#4096:fa#512:\ - :pb#21600:ob#21600:tb=swap: \ - :pc#659880:oc#0: \ - :pd#216000:od#53200:td=4.2BSD:bd#4096:fd#512: \ - :ph#398520:oh#269200:th=4.2BSD:bh#4096:fh#512: - -miniscribe9380|compaq38|Miniscribe 9380 ESDI :\ - :ty=winchester:dt=ESDI:se#512:nt#15:ns#35:nc#1223:rm#3600:sf: \ - :pa#21000:oa#0:ba#8192:fa#1024:ta=4.2BSD: \ - :pb#42000:ob#21000:tb=swap: \ - :pc#642075:oc#0: \ - :pd#21000:od#63000:bd#8192:fd#1024:td=4.2BSD: \ - :ph#556500:oh#84000:bh#8192:fh#1024:th=4.2BSD: - -ida4|compaq88|Compaq IDA (4 drives) :\ - :ty=winchester:dt=IDA:se#512:nt#16:ns#63:nc#1644:rm#3600:\ - :pa#20160:oa#0:ba#8192:fa#1024:ta=4.2BSD: \ - :pb#80640:ob#20160:tb=swap: \ - :pc#1659168:oc#0: \ - :pd#201600:od#100800:bd#8192:fd#1024:td=4.2BSD: \ - :pe#20160:oe#1310400:be#8192:fe#1024:te=4.2BSD: \ - :ph#1008000:oh#302400:bh#8192:fh#1024:th=4.2BSD: \ - :pg#302400:og#1330560:bg#4096:fg#512:tg=4.2BSD: - -fuji513|Fujitsu M22XXXX: \ - :ty=winchester:dt=ESDI:se#512:nt#16:ns#63:nc#954:rm#3600:\ - :pa#20160:oa#82656:ba#4096:fa#512:ta=4.2BSD: \ - :pb#40320:ob#102816:tb=swap: \ - :pc#961632:oc#0: \ - :ph#656208:oh#143136:bh#4096:fh#512:th=4.2BSD: - -sony650|Sony 650 MB MOD|\ - :ty=removable:dt=SCSI:se#512:nt#1:ns#31:nc#18600:ts#1:rm#4800:\ - :pc#576600:oc#0:\ - :pa#576600:oa#0:ta=4.2BSD:ba#8192:fa#1024: - -mta3230|mo230|IBM MTA-3230 230 Meg 3.5inch Magneto-Optical:\ - :ty=removeable:dt=SCSI:rm#3600:\ - :se#512:nt#64:ns#32:nc#216:sc#2048:su#444384:\ - :pa#444384:oa#0:ba#4096:fa#0:ta=4.2BSD:\ - :pc#444384:oc#0: - -minimum:ty=mfs:se#512:nt#1:rm#300:\ - :ns#2880:nc#1:\ - :pa#2880:oa#0:ba#4096:fa#512:\ - :pc#2880:oc#0:bc#4096:fc#512: - -minimum2:ty=mfs:se#512:nt#1:rm#300:\ - :ns#5760:nc#1:\ - :pa#5760:oa#0:ba#4096:fa#512:\ - :pc#5760:oc#0:bc#4096:fc#512: - -minimum3:ty=mfs:se#512:nt#1:rm#300:\ - :ns#8640:nc#1:\ - :pa#8640:oa#0:ba#4096:fa#512:\ - :pc#8640:oc#0:bc#4096:fc#512: - -zip100|zip 100:\ - :ty=removable:se#512:nc#96:nt#64:ns#32:\ - :pa#196608:oa#0:ba#4096:fa#512:\ - :pc#196608:oc#0:bc#4096:fc#512: - -zip250|zip 250:\ - :ty=removable:se#512:nc#239:nt#64:ns#32:\ - :pa#489472:oa#0:ba#4096:fa#512:\ - :pc#489472:oc#0:bc#4096:fc#512: - -orb2200|orb22|orb:\ - :ty=removable:ns#63:nt#128:nc#4273:sc#1008:su#4307184:se#512:\ - :pa#4307184:oa#0:ba#8192:fa#1024:\ - :pc#4307184:oc#0:bc#8192:fc#1024: - Index: etc/mtree/BSD.release.dist =================================================================== --- etc/mtree/BSD.release.dist +++ etc/mtree/BSD.release.dist @@ -7,8 +7,6 @@ . filesys .. - floppies - .. tarballs bindist .. Index: release/picobsd/bridge/PICOBSD =================================================================== --- release/picobsd/bridge/PICOBSD +++ release/picobsd/bridge/PICOBSD @@ -53,9 +53,6 @@ device random # used by ssh device pci -# Floppy drives -device fdc - # ATA and ATAPI devices #device ata #device atadisk # ATA disk drives Index: release/picobsd/bridge/PICOBSD.hints =================================================================== --- release/picobsd/bridge/PICOBSD.hints +++ release/picobsd/bridge/PICOBSD.hints @@ -1,10 +1,4 @@ # $FreeBSD$ -hint.fdc.0.at="isa" -hint.fdc.0.port="0x3F0" -hint.fdc.0.irq="6" -hint.fdc.0.drq="2" -hint.fd.0.at="fdc0" -hint.fd.0.drive="0" hint.ata.0.at="isa" hint.ata.0.port="0x1F0" hint.ata.0.irq="14" Index: release/picobsd/mfs_tree/etc/disktab =================================================================== --- release/picobsd/mfs_tree/etc/disktab +++ /dev/null @@ -1,85 +0,0 @@ -# $FreeBSD$ -# Floppy formats: -# -# To make a filesystem on a floppy: -# fdformat [-f ] fd[.] -# disklabel -B -r -w fd[.] fd -# newfs fd[.] -# -# with : -# -t 2 - two heads -# -u 9|15|18 - sectors per track -# (using the default value of 1/4096 is not much useful for floppies) -# -l 1 - interleave 1 (for most floppies) -# -i 65536 - bytes of data per i-node -# (the default -i value will render you with a floppy wasting way -# too much space in i-node areas) - -fd360:\ - :ty=floppy:se#512:nt#2:rm#300:ns#9:nc#40:\ - :pa#720:oa#0:ba#4096:fa#512:\ - :pb#720:ob#0:bb#4096:fb#512:\ - :pc#720:oc#0:bc#4096:fc#512: - -fd720:\ - :ty=floppy:se#512:nt#2:rm#300:ns#9:nc#80:\ - :pa#1440:oa#0:ba#4096:fa#512:\ - :pb#1440:ob#0:bb#4096:fb#512:\ - :pc#1440:oc#0:bc#4096:fc#512: - -fd1200|floppy5|5in|5.25in High Density Floppy:\ - :ty=floppy:se#512:nt#2:rm#360:ns#15:nc#80:\ - :pa#2400:oa#0:ba#4096:fa#512:\ - :pb#2400:ob#0:bb#4096:fb#512:\ - :pc#2400:oc#0:bc#4096:fc#512: - -fd1440|floppy|floppy3|3in|3.5in High Density Floppy:\ - :ty=floppy:se#512:nt#2:rm#300:ns#18:nc#80:\ - :pa#2880:oa#0:ba#4096:fa#512:\ - :pb#2880:ob#0:bb#4096:fb#512:\ - :pc#2880:oc#0:bc#4096:fc#512: - -fd1024|floppy0|3.5in Special Density Floppy:\ - :ty=floppy:se#512:nt#2:rm#300:ns#16:nc#64:\ - :pa#2048:oa#0:ba#4096:fa#512:\ - :pb#2048:ob#0:bb#4096:fb#512:\ - :pc#2048:oc#0:bc#4096:fc#512: - -# a == root -# b == swap -# c == d == whole disk -# e == /var -# f == scratch -# h == /usr - -cp3100new|Connor Peripherals 100MB IDE, with a different configuration:\ - :dt=ST506:ty=winchester:se#512:nt#8:ns#33:nc#766: \ - :pa#15840:oa#0:ta=4.2BSD:ba#4096:fa#512: \ - :pb#24288:ob#15840:tb=swap: \ - :pc#202224:oc#0: \ - :pd#202224:od#0: \ - :pe#15840:oe#40128:te=4.2BSD:be#4096:fe#512: \ - :pg#15840:og#55968:tg=4.2BSD:bg#4096:fg#512: \ - :ph#130416:oh#71808:th=4.2BSD:bh#4096:fh#512: - -sony650|Sony 650 MB MOD|\ - :ty=removable:dt=SCSI:se#512:nt#1:ns#31:nc#18600:ts#1:rm#4800:\ - :pc#576600:oc#0:\ - :pa#576600:oa#0:ta=4.2BSD:ba#8192:fa#1024: - -mta3230|mo230|IBM MTA-3230 230 Meg 3.5inch Magneto-Optical:\ - :ty=removeable:dt=SCSI:rm#3600:\ - :se#512:nt#64:ns#32:nc#216:sc#2048:su#444384:\ - :pa#444384:oa#0:ba#4096:fa#0:ta=4.2BSD:\ - :pc#444384:oc#0: - -minimum:ty=mfs:se#512:nt#1:rm#300:\ - :ns#2880:nc#1:\ - :pa#2880:oa#0:ba#4096:fa#512:\ - :pc#2880:oc#0:bc#4096:fc#512: - -zip100|zip 100:\ - :ty=removable:se#512:nc#96:nt#64:ns#32:\ - :pa#196608:oa#0:ba#4096:fa#512:\ - :pb#196608:ob#0:bb#4096:fb#512:\ - :pc#196608:oc#0:bc#4096:fc#512: Index: release/picobsd/qemu/PICOBSD =================================================================== --- release/picobsd/qemu/PICOBSD +++ release/picobsd/qemu/PICOBSD @@ -59,9 +59,6 @@ device random # used by ssh device pci -# Floppy drives -device fdc - # ATA and ATAPI devices #device ata #device atadisk # ATA disk drives Index: release/picobsd/qemu/PICOBSD.hints =================================================================== --- release/picobsd/qemu/PICOBSD.hints +++ release/picobsd/qemu/PICOBSD.hints @@ -1,10 +1,4 @@ # $FreeBSD$ -hint.fdc.0.at="isa" -hint.fdc.0.port="0x3F0" -hint.fdc.0.irq="6" -hint.fdc.0.drq="2" -hint.fd.0.at="fdc0" -hint.fd.0.drive="0" hint.ata.0.at="isa" hint.ata.0.port="0x1F0" hint.ata.0.irq="14" Index: sbin/newfs/newfs.8 =================================================================== --- sbin/newfs/newfs.8 +++ sbin/newfs/newfs.8 @@ -299,7 +299,6 @@ This large fragment size may lead to much wasted space on file systems that contain many small files. .Sh SEE ALSO -.Xr fdformat 1 , .Xr geom 4 , .Xr disktab 5 , .Xr fs 5 , Index: share/man/man4/Makefile =================================================================== --- share/man/man4/Makefile +++ share/man/man4/Makefile @@ -156,7 +156,6 @@ exca.4 \ e6060sw.4 \ fd.4 \ - fdc.4 \ fdt.4 \ fdtbus.4 \ ffclock.4 \ Index: share/man/man4/fdc.4 =================================================================== --- share/man/man4/fdc.4 +++ /dev/null @@ -1,335 +0,0 @@ -.\" -.\" Copyright (c) 1994 Wilko Bulte -.\" Copyright (c) 2001 Joerg Wunsch -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd April 7, 2017 -.Dt FDC 4 -.Os -.Sh NAME -.Nm fdc -.Nd "PC architecture floppy disk controller driver" -.Sh SYNOPSIS -.Cd device fdc -.Pp -In -.Pa /boot/device.hints : -.Cd hint.fdc.0.at="isa" -.Cd hint.fdc.0.port="0x3F0" -.Cd hint.fdc.0.irq="6" -.Cd hint.fdc.0.drq="2" -.Cd hint.fdc.0.flags="0x0" -.Cd hint.fd.0.at="fdc0" -.Cd hint.fd.0.drive="0" -.Cd hint.fd.0.flags="0x0" -.Cd hint.fd.1.at="fdc0" -.Cd hint.fd.1.drive="1" -.Cd hint.fd.1.flags="0x0" -.Sh DESCRIPTION -.Ss Device Usage -This driver provides access to floppy disk drives. -Floppy disks using -either FM (single-density) or MFM (double or high-density) recording -can be handled. -.Pp -Floppy disk controllers can connect up to four drives each. -The -.Nm -driver can currently handle up to two drives per controller (or four -drives on ACPI). -Upon -driver initialization, an attempt is made to find out the type of the -floppy controller in use. -The known controller types are either the -original NE765 or i8272 chips, or alternatively -.Em enhanced -controllers that are compatible with the NE72065 or i82077 chips. -These enhanced controllers (among other enhancements) implement a FIFO -for floppy data transfers that will automatically be enabled once an -enhanced chip has been detected. -This FIFO activation can be disabled -using the per-controller flags value of -.Ar 0x1 . -.Pp -By default, this driver creates a single device node -.Pa /dev/fd Ns Ar N -for each attached drive with number -.Ar N . -For historical reasons, device nodes that use a trailing UFS-style -partition letter (ranging from -.Sq a -through -.Sq h ) -can also be accessed, which will be implemented as symbolic links to -the main device node. -.Pp -Accessing the main device node will attempt to autodetect the density -of the available medium for multi-density devices. -Thus it is -possible to use either a 720 KB medium or a 1440 KB medium in a -high-density 3.5 inch standard floppy drive. -Normally, this -autodetection will only happen once at the first call to -.Xr open 2 -for the device after inserting the medium. -This assumes the drive -offers proper changeline support so media changes can be detected by -the driver. -To indicate a drive that does not have the changeline support, -this can be overridden using the per-drive device flags value of -.Ar 0x10 -(causing each call to -.Xr open 2 -to perform the autodetection). -.Pp -When trying to use a floppy device with special-density media, other -device nodes can be created, of the form -.Pa /dev/fd Ns Ar N . Ns Ar MMMM , -where -.Ar N -is the drive number, and -.Ar MMMM -is a number between one and four digits describing the device density. -Up to 15 additional subdevices per drive can be created that way. -The -administrator is free to decide on a policy how to assign these -numbers. -The two common policies are to either implement subdevices -numbered 1 through 15, or to use a number that describes the medium -density in kilobytes. -Initially, each of those devices will be -configured to the maximal density that is possible for the drive type -(like 1200 KB for 5.25 inch HD drives or 1440 KB for 3.5 inch HD -drives). -The desired density to be used on that subdevice needs to be -configured using -.Xr fdcontrol 8 . -.Pp -Drive types are configured using the lower four bits of the per-drive -device flags. -The following values can be specified: -.Bl -tag -width 2n -offset indent -.It Ar 1 -5.25 inch double-density device with 40 cylinders (360 KB native -capacity) -.It Ar 2 -5.25 inch high-density device with 80 cylinders (1200 KB native -capacity) -.It Ar 3 -3.5 inch double-density device with 80 cylinders (720 KB native -capacity) -.It Ar 4 -3.5 inch high-density device with 80 cylinders (1440 KB native -capacity) -.It Ar 5 -3.5 inch extra-density device with 80 cylinders (2880 KB native -capacity, usage currently restricted to at most 1440 KB media) -.It Ar 6 -Same as type 5, available for compatibility with some BIOSes -.El -.Pp -On IA32 architectures, the drive type can be specified as 0 for the -drives. -In that case, the CMOS configuration memory will be -consulted to obtain the value for that drive. -The ACPI probe automatically determines these values via the _FDE and -_FDI methods, but this can be overridden by specifying a drive type hint. -.Pp -Normally, each configured drive will be probed at initialization -time, using a short seek sequence. -This is intended to find out about -drives that have been configured but are actually missing or -otherwise not responding. -(The ACPI probe method does not perform this seek.) -In some environments (like laptops with -detachable drives), it might be desirable to bypass this drive probe, -and pretend a drive to be there so the driver autoconfiguration will -work even if the drive is currently not present. -For that purpose, a -per-drive device flags value of -.Ar 0x20 -needs to be specified. -.Ss Programming Interface -In addition to the normal read and write functionality, the -.Nm -driver offers a number of configurable options using -.Xr ioctl 2 . -In order to access any of this functionality, programmers need to -include the header file -.In sys/fdcio.h -into their programs. -The call to -.Xr open 2 -can be performed in two possible ways. -When opening the device -without the -.Dv O_NONBLOCK -flag set, the device is opened in a normal way, which would cause the -main device nodes to perform automatic media density selection, and which -will yield a file descriptor that is fully available for any I/O operation -or any of the following -.Xr ioctl 2 -commands. -.Pp -When opening the device with -.Dv O_NONBLOCK -set, automatic media density selection will be bypassed, and the device -remains in a half-opened state. -No actual I/O operations are possible, but -many of the -.Xr ioctl 2 -commands described below can be performed. -This mode is intended for -access to the device without the requirement to have an accessible -media present, like for status inquiries to the drive, or in order to -format a medium. -.Dv O_NONBLOCK -needs to be cleared before I/O operations are possible on the descriptor, -which requires a prior specification of the density using the -.Dv FD_STYPE -command (see below). -Operations that are not allowed on the half-opened -descriptor will cause an error value of -.Er EAGAIN . -.Pp -The following -.Xr ioctl 2 -commands are currently available: -.Bl -tag -width ".Dv FD_READID" -.It Dv FD_FORM -Used to format a floppy disk medium. -Third argument is a pointer to a -.Vt "struct fd_formb" -specifying which track to format, and which parameters to fill into -the ID fields of the floppy disk medium. -.It Dv FD_GTYPE -Returns the current density definition record for the selected device. -Third argument is a pointer to -.Vt "struct fd_type" . -.It Dv FD_STYPE -Adjusts the density definition of the selected device. -Third argument -is a pointer to -.Vt "struct fd_type" . -For the fixed-density subdevices (1 through 15 per drive), this -operation is restricted to a process with superuser privileges. -For -the auto-selecting subdevice 0, the operation is temporarily allowed -to any process, but this setting will be lost again upon the next -autoselection. -This can be used when formatting a new medium (which -will require to open the device using -.Dv O_NONBLOCK , -and thus to later adjust the density using -.Dv FD_STYPE ) . -.It Dv FD_GOPTS -Obtain the current drive options. -Third argument is a pointer to -.Vt int , -containing a bitwise union of the following possible flag values: -.Bl -tag -width ".Dv FDOPT_NOERRLOG" -.It Dv FDOPT_NORETRY -Do not automatically retry operations upon failure. -.It Dv FDOPT_NOERRLOG -Do not cause -.Dq "hard error" -kernel logs for failed I/O operations. -.It Dv FDOPT_NOERROR -Do not indicate I/O errors when returning from -.Xr read 2 -or -.Xr write 2 -system calls. -The caller is assumed to use -.Dv FD_GSTAT -calls in order to inquire about the success of each operation. -This -is intended to allow even erroneous data from bad blocks to be -retrieved using normal I/O operations. -.It Dv FDOPT_AUTOSEL -Device performs automatic density selection. -Unlike the above flags, -this one is read-only. -.El -.It Dv FD_SOPTS -Set device options, see above for their meaning. -Third argument is a -pointer to -.Vt int . -Drive options will always be cleared when closing the descriptor. -.It Dv FD_CLRERR -Clear the internal low-level error counter. -Normally, controller-level -I/O errors are only logged up to -.Dv FDC_ERRMAX -errors (currently defined to 100). -This command resets the counter. -Requires superuser privileges. -.It Dv FD_READID -Read one sector ID field from the floppy disk medium. -Third argument is -a pointer to -.Vt "struct fdc_readid" , -where the read data will be returned. -Can be used to analyze a floppy -disk medium. -.It Dv FD_GSTAT -Return the recent floppy disk controller status, if available. -Third -argument is a pointer to -.Vt "struct fdc_status" , -where the status registers (ST0, ST1, ST2, C, H, R, and N) are being -returned. -.Er EINVAL -will be caused if no recent status is available. -.It Dv FD_GDTYPE -Returns the floppy disk drive type. -Third argument is a pointer to -.Vt "enum fd_drivetype" . -This type is the same as being used in the per-drive configuration -flags, or in the CMOS configuration data or ACPI namespace on IA32 systems. -.El -.Sh FILES -.Bl -tag -width ".Pa /dev/fd*" -compact -.It Pa /dev/fd* -floppy disk device nodes -.El -.Sh SEE ALSO -.Xr fdformat 1 , -.Xr fdread 1 , -.Xr fdwrite 1 , -.Xr ioctl 2 , -.Xr open 2 , -.Xr read 2 , -.Xr write 2 , -.Xr fdcontrol 8 -.Sh AUTHORS -.An -nosplit -This man page was initially written by -.An Wilko Bulte , -and later vastly rewritten by -.An J\(:org Wunsch . Index: share/man/man7/hier.7 =================================================================== --- share/man/man7/hier.7 +++ share/man/man7/hier.7 @@ -151,8 +151,7 @@ .Pa /sbin .It Pa /media/ contains subdirectories to be used as mount points -for removable media such as CDs, USB drives, and -floppy disks +for removable media such as CDs, and USB drives. .It Pa /mnt/ empty directory commonly used by system administrators as a temporary mount point Index: share/man/man8/picobsd.8 =================================================================== --- share/man/man8/picobsd.8 +++ share/man/man8/picobsd.8 @@ -17,7 +17,7 @@ .Fx (historically called .Nm PicoBSD ) -which typically fits on a small media such as a floppy disk, +which typically fits on a small media, or can be downloaded as a single image file from some media such as CDROM, flash memory, or through etherboot. @@ -43,7 +43,7 @@ file system with files from the boot media (if present), and executes a specialized version of .Pa /etc/rc . -The boot media (floppy, etc.) is +The boot media is required for loading only, and typically used read-only. After the boot phase, the system runs entirely from RAM. .Pp Index: stand/i386/boot0/boot0.S =================================================================== --- stand/i386/boot0/boot0.S +++ stand/i386/boot0/boot0.S @@ -220,8 +220,6 @@ * If the 'setdrv' flag is set in the boot sector, use the drive * number from the boot sector at 'setdrv_num'. * Optionally, do the same if the BIOS gives us an invalid number - * (note though that the override prevents booting from a floppy - * or a ZIP/flash drive in floppy emulation). * The test costs 4 bytes of code so it is disabled by default. */ testb $SETDRV,_FLAGS(%bp) # Set drive number? @@ -564,10 +562,6 @@ movb $0x1,%al # Sector count pushw %si # Save movw %sp,%di # Save -#ifndef CHECK_DRIVE /* floppy support */ - testb %dl, %dl # is this a floppy ? - jz 1f # Yes, use CHS mode -#endif testb $USEPACKET,_FLAGS(%bp) # Use packet interface? jz 1f # No pushl $0x0 # Set the Index: sys/amd64/conf/GENERIC =================================================================== --- sys/amd64/conf/GENERIC +++ sys/amd64/conf/GENERIC @@ -112,9 +112,6 @@ options PCI_HP # PCI-Express native HotPlug options PCI_IOV # PCI SR-IOV support -# Floppy drives -device fdc - # ATA controllers device ahci # AHCI-compatible SATA controllers device ata # Legacy ATA/SATA controllers Index: sys/amd64/conf/GENERIC.hints =================================================================== --- sys/amd64/conf/GENERIC.hints +++ sys/amd64/conf/GENERIC.hints @@ -1,12 +1,4 @@ # $FreeBSD$ -hint.fdc.0.at="isa" -hint.fdc.0.port="0x3F0" -hint.fdc.0.irq="6" -hint.fdc.0.drq="2" -hint.fd.0.at="fdc0" -hint.fd.0.drive="0" -hint.fd.1.at="fdc0" -hint.fd.1.drive="1" hint.atkbdc.0.at="isa" hint.atkbdc.0.port="0x060" hint.atkbd.0.at="atkbdc" Index: sys/arm/conf/NOTES =================================================================== --- sys/arm/conf/NOTES +++ sys/arm/conf/NOTES @@ -63,7 +63,6 @@ nooptions COMPAT_FREEBSD9 nooption PPC_PROBE_CHIPSET -nodevice fdc nodevice sym nodevice ukbd Index: sys/conf/NOTES =================================================================== --- sys/conf/NOTES +++ sys/conf/NOTES @@ -1800,32 +1800,6 @@ #options ATA_REQUEST_TIMEOUT=10 # -# Standard floppy disk controllers and floppy tapes, supports -# the Y-E DATA External FDD (PC Card) -# -device fdc -hint.fdc.0.at="isa" -hint.fdc.0.port="0x3F0" -hint.fdc.0.irq="6" -hint.fdc.0.drq="2" -# -# FDC_DEBUG enables floppy debugging. Since the debug output is huge, you -# gotta turn it actually on by setting the variable fd_debug with DDB, -# however. -options FDC_DEBUG -# -# Activate this line if you happen to have an Insight floppy tape. -# Probing them proved to be dangerous for people with floppy disks only, -# so it's "hidden" behind a flag: -#hint.fdc.0.flags="1" - -# Specify floppy devices -hint.fd.0.at="fdc0" -hint.fd.0.drive="0" -hint.fd.1.at="fdc0" -hint.fd.1.drive="1" - -# # uart: newbusified driver for serial interfaces. It consolidates the sio(4), # sab(4) and zs(4) drivers. # Index: sys/conf/files.amd64 =================================================================== --- sys/conf/files.amd64 +++ sys/conf/files.amd64 @@ -288,10 +288,6 @@ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_adminq.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" -dev/fdc/fdc.c optional fdc -dev/fdc/fdc_acpi.c optional fdc -dev/fdc/fdc_isa.c optional fdc isa -dev/fdc/fdc_pccard.c optional fdc pccard dev/gpio/bytgpio.c optional bytgpio dev/hpt27xx/hpt27xx_os_bsd.c optional hpt27xx dev/hpt27xx/hpt27xx_osm_bsd.c optional hpt27xx Index: sys/conf/files.i386 =================================================================== --- sys/conf/files.i386 +++ sys/conf/files.i386 @@ -205,10 +205,6 @@ dev/fb/s3_pci.c optional s3pci dev/fb/vesa.c optional vga vesa dev/fb/vga.c optional vga -dev/fdc/fdc.c optional fdc -dev/fdc/fdc_acpi.c optional fdc -dev/fdc/fdc_isa.c optional fdc isa -dev/fdc/fdc_pccard.c optional fdc pccard dev/fe/if_fe_isa.c optional fe isa dev/glxiic/glxiic.c optional glxiic dev/glxsb/glxsb.c optional glxsb Index: sys/conf/options =================================================================== --- sys/conf/options +++ sys/conf/options @@ -682,7 +682,6 @@ ROOTDEVNAME -FDC_DEBUG opt_fdc.h PCFCLOCK_VERBOSE opt_pcfclock.h PCFCLOCK_MAX_RETRIES opt_pcfclock.h Index: sys/dev/acpica/acpi.c =================================================================== --- sys/dev/acpica/acpi.c +++ sys/dev/acpica/acpi.c @@ -809,7 +809,7 @@ * If this device is an ACPI child but no one claimed it, attempt * to power it off. We'll power it back up when a driver is added. * - * XXX Disabled for now since many necessary devices (like fdc and + * XXX Disabled for now since many necessary devices (like * ATA) don't claim the devices we created for them but still expect * them to be powered up. */ @@ -1044,8 +1044,6 @@ * 'value + 2' in the port resources instead of the hint * value. */ - if (strcmp(name, "fdc") == 0) - value += 2; if (acpi_match_resource_hint(child, SYS_RES_IOPORT, value)) matches++; else Index: sys/dev/fdc/fdc.c =================================================================== --- sys/dev/fdc/fdc.c +++ /dev/null @@ -1,2106 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 2004 Poul-Henning Kamp - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Don Ahn. - * - * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu) - * aided by the Linux floppy driver modifications from David Bateman - * (dbateman@eng.uts.edu.au). - * - * Copyright (c) 1993, 1994 by - * jc@irbs.UUCP (John Capo) - * vak@zebub.msk.su (Serge Vakulenko) - * ache@astral.msk.su (Andrew A. Chernov) - * - * Copyright (c) 1993, 1994, 1995 by - * joerg_wunsch@uriah.sax.de (Joerg Wunsch) - * dufault@hda.com (Peter Dufault) - * - * Copyright (c) 2001 Joerg Wunsch, - * joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_fdc.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -/* - * Runtime configuration hints/flags - */ - -/* configuration flags for fd */ -#define FD_TYPEMASK 0x0f /* drive type, matches enum - * fd_drivetype; on i386 machines, if - * given as 0, use RTC type for fd0 - * and fd1 */ -#define FD_NO_CHLINE 0x10 /* drive does not support changeline - * aka. unit attention */ -#define FD_NO_PROBE 0x20 /* don't probe drive (seek test), just - * assume it is there */ - -/* - * Things that could conceiveably considered parameters or tweakables - */ - -/* - * Maximal number of bytes in a cylinder. - * This is used for ISADMA bouncebuffer allocation and sets the max - * xfersize we support. - * - * 2.88M format has 2 x 36 x 512, allow for hacked up density. - */ -#define MAX_BYTES_PER_CYL (2 * 40 * 512) - -/* - * Timeout value for the PIO loops to wait until the FDC main status - * register matches our expectations (request for master, direction - * bit). This is supposed to be a number of microseconds, although - * timing might actually not be very accurate. - * - * Timeouts of 100 msec are believed to be required for some broken - * (old) hardware. - */ -#define FDSTS_TIMEOUT 100000 - -/* - * After this many errors, stop whining. Close will reset this count. - */ -#define FDC_ERRMAX 100 - -/* - * AutoDensity search lists for each drive type. - */ - -static struct fd_type fd_searchlist_360k[] = { - { FDF_5_360 }, - { 0 } -}; - -static struct fd_type fd_searchlist_12m[] = { - { FDF_5_1200 | FL_AUTO }, - { FDF_5_400 | FL_AUTO }, - { FDF_5_360 | FL_2STEP | FL_AUTO}, - { 0 } -}; - -static struct fd_type fd_searchlist_720k[] = { - { FDF_3_720 }, - { 0 } -}; - -static struct fd_type fd_searchlist_144m[] = { - { FDF_3_1440 | FL_AUTO}, - { FDF_3_720 | FL_AUTO}, - { 0 } -}; - -static struct fd_type fd_searchlist_288m[] = { - { FDF_3_1440 | FL_AUTO }, -#if 0 - { FDF_3_2880 | FL_AUTO }, /* XXX: probably doesn't work */ -#endif - { FDF_3_720 | FL_AUTO}, - { 0 } -}; - -/* - * Order must match enum fd_drivetype in . - */ -static struct fd_type *fd_native_types[] = { - NULL, /* FDT_NONE */ - fd_searchlist_360k, /* FDT_360K */ - fd_searchlist_12m, /* FDT_12M */ - fd_searchlist_720k, /* FDT_720K */ - fd_searchlist_144m, /* FDT_144M */ - fd_searchlist_288m, /* FDT_288M_1 (mapped to FDT_288M) */ - fd_searchlist_288m, /* FDT_288M */ -}; - -/* - * Internals start here - */ - -/* registers */ -#define FDOUT 2 /* Digital Output Register (W) */ -#define FDO_FDSEL 0x03 /* floppy device select */ -#define FDO_FRST 0x04 /* floppy controller reset */ -#define FDO_FDMAEN 0x08 /* enable floppy DMA and Interrupt */ -#define FDO_MOEN0 0x10 /* motor enable drive 0 */ -#define FDO_MOEN1 0x20 /* motor enable drive 1 */ -#define FDO_MOEN2 0x40 /* motor enable drive 2 */ -#define FDO_MOEN3 0x80 /* motor enable drive 3 */ - -#define FDSTS 4 /* NEC 765 Main Status Register (R) */ -#define FDDSR 4 /* Data Rate Select Register (W) */ -#define FDDATA 5 /* NEC 765 Data Register (R/W) */ -#define FDCTL 7 /* Control Register (W) */ - -/* - * The YE-DATA PC Card floppies use PIO to read in the data rather - * than DMA due to the wild variability of DMA for the PC Card - * devices. DMA was deleted from the PC Card specification in version - * 7.2 of the standard, but that post-dates the YE-DATA devices by many - * years. - * - * In addition, if we cannot setup the DMA resources for the ISA - * attachment, we'll use this same offset for data transfer. However, - * that almost certainly won't work. - * - * For this mode, offset 0 and 1 must be used to setup the transfer - * for this floppy. This is OK for PC Card YE Data devices, but for - * ISA this is likely wrong. These registers are only available on - * those systems that map them to the floppy drive. Newer systems do - * not do this, and we should likely prohibit access to them (or - * disallow NODMA to be set). - */ -#define FDBCDR 0 /* And 1 */ -#define FD_YE_DATAPORT 6 /* Drive Data port */ - -#define FDI_DCHG 0x80 /* diskette has been changed */ - /* requires drive and motor being selected */ - /* is cleared by any step pulse to drive */ - -/* - * We have three private BIO commands. - */ -#define BIO_PROBE BIO_CMD0 -#define BIO_RDID BIO_CMD1 -#define BIO_FMT BIO_CMD2 - -/* - * Per drive structure (softc). - */ -struct fd_data { - u_char *fd_ioptr; /* IO pointer */ - u_int fd_iosize; /* Size of IO chunks */ - u_int fd_iocount; /* Outstanding requests */ - struct fdc_data *fdc; /* pointer to controller structure */ - int fdsu; /* this units number on this controller */ - enum fd_drivetype type; /* drive type */ - struct fd_type *ft; /* pointer to current type descriptor */ - struct fd_type fts; /* type descriptors */ - int sectorsize; - int flags; -#define FD_WP (1<<0) /* Write protected */ -#define FD_MOTOR (1<<1) /* motor should be on */ -#define FD_MOTORWAIT (1<<2) /* motor should be on */ -#define FD_EMPTY (1<<3) /* no media */ -#define FD_NEWDISK (1<<4) /* media changed */ -#define FD_ISADMA (1<<5) /* isa dma started */ - int track; /* where we think the head is */ -#define FD_NO_TRACK -2 - int options; /* FDOPT_* */ - struct callout toffhandle; - struct g_geom *fd_geom; - struct g_provider *fd_provider; - device_t dev; - struct bio_queue_head fd_bq; -}; - -#define FD_NOT_VALID -2 - -static driver_intr_t fdc_intr; -static driver_filter_t fdc_intr_fast; -static void fdc_reset(struct fdc_data *); -static int fd_probe_disk(struct fd_data *, int *); - -static SYSCTL_NODE(_debug, OID_AUTO, fdc, CTLFLAG_RW, 0, "fdc driver"); - -static int fifo_threshold = 8; -SYSCTL_INT(_debug_fdc, OID_AUTO, fifo, CTLFLAG_RW, &fifo_threshold, 0, - "FIFO threshold setting"); - -static int debugflags = 0; -SYSCTL_INT(_debug_fdc, OID_AUTO, debugflags, CTLFLAG_RW, &debugflags, 0, - "Debug flags"); - -static int retries = 10; -SYSCTL_INT(_debug_fdc, OID_AUTO, retries, CTLFLAG_RW, &retries, 0, - "Number of retries to attempt"); - -static int spec1 = NE7_SPEC_1(6, 240); -SYSCTL_INT(_debug_fdc, OID_AUTO, spec1, CTLFLAG_RW, &spec1, 0, - "Specification byte one (step-rate + head unload)"); - -static int spec2 = NE7_SPEC_2(16, 0); -SYSCTL_INT(_debug_fdc, OID_AUTO, spec2, CTLFLAG_RW, &spec2, 0, - "Specification byte two (head load time + no-dma)"); - -static int settle; -SYSCTL_INT(_debug_fdc, OID_AUTO, settle, CTLFLAG_RW, &settle, 0, - "Head settling time in sec/hz"); - -static void -fdprinttype(struct fd_type *ft) -{ - - printf("(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,0x%x)", - ft->sectrac, ft->secsize, ft->datalen, ft->gap, ft->tracks, - ft->size, ft->trans, ft->heads, ft->f_gap, ft->f_inter, - ft->offset_side2, ft->flags); -} - -static void -fdsettype(struct fd_data *fd, struct fd_type *ft) -{ - fd->ft = ft; - ft->size = ft->sectrac * ft->heads * ft->tracks; - fd->sectorsize = 128 << fd->ft->secsize; -} - -/* - * Bus space handling (access to low-level IO). - */ -static inline void -fdregwr(struct fdc_data *fdc, int reg, uint8_t v) -{ - - bus_space_write_1(fdc->iot, fdc->ioh[reg], fdc->ioff[reg], v); -} - -static inline uint8_t -fdregrd(struct fdc_data *fdc, int reg) -{ - - return bus_space_read_1(fdc->iot, fdc->ioh[reg], fdc->ioff[reg]); -} - -static void -fdctl_wr(struct fdc_data *fdc, u_int8_t v) -{ - - fdregwr(fdc, FDCTL, v); -} - -static void -fdout_wr(struct fdc_data *fdc, u_int8_t v) -{ - - fdregwr(fdc, FDOUT, v); -} - -static u_int8_t -fdsts_rd(struct fdc_data *fdc) -{ - - return fdregrd(fdc, FDSTS); -} - -static void -fddsr_wr(struct fdc_data *fdc, u_int8_t v) -{ - - fdregwr(fdc, FDDSR, v); -} - -static void -fddata_wr(struct fdc_data *fdc, u_int8_t v) -{ - - fdregwr(fdc, FDDATA, v); -} - -static u_int8_t -fddata_rd(struct fdc_data *fdc) -{ - - return fdregrd(fdc, FDDATA); -} - -static u_int8_t -fdin_rd(struct fdc_data *fdc) -{ - - return fdregrd(fdc, FDCTL); -} - -/* - * Magic pseudo-DMA initialization for YE FDC. Sets count and - * direction. - */ -static void -fdbcdr_wr(struct fdc_data *fdc, int iswrite, uint16_t count) -{ - fdregwr(fdc, FDBCDR, (count - 1) & 0xff); - fdregwr(fdc, FDBCDR + 1, - (iswrite ? 0x80 : 0) | (((count - 1) >> 8) & 0x7f)); -} - -static int -fdc_err(struct fdc_data *fdc, const char *s) -{ - fdc->fdc_errs++; - if (s) { - if (fdc->fdc_errs < FDC_ERRMAX) - device_printf(fdc->fdc_dev, "%s", s); - else if (fdc->fdc_errs == FDC_ERRMAX) - device_printf(fdc->fdc_dev, "too many errors, not " - "logging any more\n"); - } - - return (1); -} - -/* - * FDC IO functions, take care of the main status register, timeout - * in case the desired status bits are never set. - * - * These PIO loops initially start out with short delays between - * each iteration in the expectation that the required condition - * is usually met quickly, so it can be handled immediately. - */ -static int -fdc_in(struct fdc_data *fdc, int *ptr) -{ - int i, j, step; - - step = 1; - for (j = 0; j < FDSTS_TIMEOUT; j += step) { - i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM); - if (i == (NE7_DIO|NE7_RQM)) { - i = fddata_rd(fdc); - if (ptr) - *ptr = i; - return (0); - } - if (i == NE7_RQM) - return (fdc_err(fdc, "ready for output in input\n")); - step += step; - DELAY(step); - } - return (fdc_err(fdc, bootverbose? "input ready timeout\n": 0)); -} - -static int -fdc_out(struct fdc_data *fdc, int x) -{ - int i, j, step; - - step = 1; - for (j = 0; j < FDSTS_TIMEOUT; j += step) { - i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM); - if (i == NE7_RQM) { - fddata_wr(fdc, x); - return (0); - } - if (i == (NE7_DIO|NE7_RQM)) - return (fdc_err(fdc, "ready for input in output\n")); - step += step; - DELAY(step); - } - return (fdc_err(fdc, bootverbose? "output ready timeout\n": 0)); -} - -/* - * fdc_cmd: Send a command to the chip. - * Takes a varargs with this structure: - * # of output bytes - * output bytes as int [...] - * # of input bytes - * input bytes as int* [...] - */ -static int -fdc_cmd(struct fdc_data *fdc, int n_out, ...) -{ - u_char cmd = 0; - int n_in; - int n, i; - va_list ap; - - va_start(ap, n_out); - for (n = 0; n < n_out; n++) { - i = va_arg(ap, int); - if (n == 0) - cmd = i; - if (fdc_out(fdc, i) < 0) { - char msg[50]; - snprintf(msg, sizeof(msg), - "cmd %x failed at out byte %d of %d\n", - cmd, n + 1, n_out); - fdc->flags |= FDC_NEEDS_RESET; - va_end(ap); - return fdc_err(fdc, msg); - } - } - n_in = va_arg(ap, int); - for (n = 0; n < n_in; n++) { - int *ptr = va_arg(ap, int *); - if (fdc_in(fdc, ptr) < 0) { - char msg[50]; - snprintf(msg, sizeof(msg), - "cmd %02x failed at in byte %d of %d\n", - cmd, n + 1, n_in); - fdc->flags |= FDC_NEEDS_RESET; - va_end(ap); - return fdc_err(fdc, msg); - } - } - va_end(ap); - return (0); -} - -static void -fdc_reset(struct fdc_data *fdc) -{ - int i, r[10]; - - if (fdc->fdct == FDC_ENHANCED) { - /* Try a software reset, default precomp, and 500 kb/s */ - fddsr_wr(fdc, I8207X_DSR_SR); - } else { - /* Try a hardware reset, keep motor on */ - fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); - DELAY(100); - /* enable FDC, but defer interrupts a moment */ - fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN); - } - DELAY(100); - fdout_wr(fdc, fdc->fdout); - - /* XXX after a reset, silently believe the FDC will accept commands */ - if (fdc_cmd(fdc, 3, NE7CMD_SPECIFY, spec1, spec2, 0)) - device_printf(fdc->fdc_dev, " SPECIFY failed in reset\n"); - - if (fdc->fdct == FDC_ENHANCED) { - if (fdc_cmd(fdc, 4, - I8207X_CONFIG, - 0, - /* 0x40 | */ /* Enable Implied Seek - - * breaks 2step! */ - 0x10 | /* Polling disabled */ - (fifo_threshold - 1), /* Fifo threshold */ - 0x00, /* Precomp track */ - 0)) - device_printf(fdc->fdc_dev, - " CONFIGURE failed in reset\n"); - if (debugflags & 1) { - if (fdc_cmd(fdc, 1, - I8207X_DUMPREG, - 10, &r[0], &r[1], &r[2], &r[3], &r[4], - &r[5], &r[6], &r[7], &r[8], &r[9])) - device_printf(fdc->fdc_dev, - " DUMPREG failed in reset\n"); - for (i = 0; i < 10; i++) - printf(" %02x", r[i]); - printf("\n"); - } - } -} - -static int -fdc_sense_drive(struct fdc_data *fdc, int *st3p) -{ - int st3; - - if (fdc_cmd(fdc, 2, NE7CMD_SENSED, fdc->fd->fdsu, 1, &st3)) - return (fdc_err(fdc, "Sense Drive Status failed\n")); - if (st3p) - *st3p = st3; - return (0); -} - -static int -fdc_sense_int(struct fdc_data *fdc, int *st0p, int *cylp) -{ - int cyl, st0, ret; - - ret = fdc_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0); - if (ret) { - (void)fdc_err(fdc, "sense intr err reading stat reg 0\n"); - return (ret); - } - - if (st0p) - *st0p = st0; - - if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) { - /* - * There doesn't seem to have been an interrupt. - */ - return (FD_NOT_VALID); - } - - if (fdc_in(fdc, &cyl) < 0) - return fdc_err(fdc, "can't get cyl num\n"); - - if (cylp) - *cylp = cyl; - - return (0); -} - -static int -fdc_read_status(struct fdc_data *fdc) -{ - int i, ret, status; - - for (i = ret = 0; i < 7; i++) { - ret = fdc_in(fdc, &status); - fdc->status[i] = status; - if (ret != 0) - break; - } - - if (ret == 0) - fdc->flags |= FDC_STAT_VALID; - else - fdc->flags &= ~FDC_STAT_VALID; - - return ret; -} - -/* - * Select this drive - */ -static void -fd_select(struct fd_data *fd) -{ - struct fdc_data *fdc; - - /* XXX: lock controller */ - fdc = fd->fdc; - fdc->fdout &= ~FDO_FDSEL; - fdc->fdout |= FDO_FDMAEN | FDO_FRST | fd->fdsu; - fdout_wr(fdc, fdc->fdout); -} - -static void -fd_turnon(void *arg) -{ - struct fd_data *fd; - struct bio *bp; - int once; - - fd = arg; - mtx_assert(&fd->fdc->fdc_mtx, MA_OWNED); - fd->flags &= ~FD_MOTORWAIT; - fd->flags |= FD_MOTOR; - once = 0; - for (;;) { - bp = bioq_takefirst(&fd->fd_bq); - if (bp == NULL) - break; - bioq_disksort(&fd->fdc->head, bp); - once = 1; - } - if (once) - wakeup(&fd->fdc->head); -} - -static void -fd_motor(struct fd_data *fd, int turnon) -{ - struct fdc_data *fdc; - - fdc = fd->fdc; -/* - mtx_assert(&fdc->fdc_mtx, MA_OWNED); -*/ - if (turnon) { - fd->flags |= FD_MOTORWAIT; - fdc->fdout |= (FDO_MOEN0 << fd->fdsu); - callout_reset(&fd->toffhandle, hz, fd_turnon, fd); - } else { - callout_stop(&fd->toffhandle); - fd->flags &= ~(FD_MOTOR|FD_MOTORWAIT); - fdc->fdout &= ~(FDO_MOEN0 << fd->fdsu); - } - fdout_wr(fdc, fdc->fdout); -} - -static void -fd_turnoff(void *xfd) -{ - struct fd_data *fd = xfd; - - mtx_assert(&fd->fdc->fdc_mtx, MA_OWNED); - fd_motor(fd, 0); -} - -/* - * fdc_intr - wake up the worker thread. - */ - -static void -fdc_intr(void *arg) -{ - - wakeup(arg); -} - -static int -fdc_intr_fast(void *arg) -{ - - wakeup(arg); - return(FILTER_HANDLED); -} - -/* - * fdc_pio(): perform programmed IO read/write for YE PCMCIA floppy. - */ -static void -fdc_pio(struct fdc_data *fdc) -{ - u_char *cptr; - struct bio *bp; - u_int count; - - bp = fdc->bp; - cptr = fdc->fd->fd_ioptr; - count = fdc->fd->fd_iosize; - - if (bp->bio_cmd == BIO_READ) { - fdbcdr_wr(fdc, 0, count); - bus_space_read_multi_1(fdc->iot, fdc->ioh[FD_YE_DATAPORT], - fdc->ioff[FD_YE_DATAPORT], cptr, count); - } else { - bus_space_write_multi_1(fdc->iot, fdc->ioh[FD_YE_DATAPORT], - fdc->ioff[FD_YE_DATAPORT], cptr, count); - fdbcdr_wr(fdc, 0, count); /* needed? */ - } -} - -static int -fdc_biodone(struct fdc_data *fdc, int error) -{ - struct fd_data *fd; - struct bio *bp; - - fd = fdc->fd; - bp = fdc->bp; - - mtx_lock(&fdc->fdc_mtx); - if (--fd->fd_iocount == 0) - callout_reset(&fd->toffhandle, 4 * hz, fd_turnoff, fd); - fdc->bp = NULL; - fdc->fd = NULL; - mtx_unlock(&fdc->fdc_mtx); - if (bp->bio_to != NULL) { - if ((debugflags & 2) && fd->fdc->retry > 0) - printf("retries: %d\n", fd->fdc->retry); - g_io_deliver(bp, error); - return (0); - } - bp->bio_error = error; - bp->bio_flags |= BIO_DONE; - wakeup(bp); - return (0); -} - -static int retry_line; - -static int -fdc_worker(struct fdc_data *fdc) -{ - struct fd_data *fd; - struct bio *bp; - int i, nsect; - int st0, st3, cyl, mfm, steptrac, cylinder, descyl, sec; - int head; - int override_error; - static int need_recal; - struct fdc_readid *idp; - struct fd_formb *finfo; - - override_error = 0; - - /* Have we exhausted our retries ? */ - bp = fdc->bp; - fd = fdc->fd; - if (bp != NULL && - (fdc->retry >= retries || (fd->options & FDOPT_NORETRY))) { - if ((debugflags & 4)) - printf("Too many retries (EIO)\n"); - if (fdc->flags & FDC_NEEDS_RESET) { - mtx_lock(&fdc->fdc_mtx); - fd->flags |= FD_EMPTY; - mtx_unlock(&fdc->fdc_mtx); - } - return (fdc_biodone(fdc, EIO)); - } - - /* Disable ISADMA if we bailed while it was active */ - if (fd != NULL && (fd->flags & FD_ISADMA)) { - isa_dmadone( - bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE, - fd->fd_ioptr, fd->fd_iosize, fdc->dmachan); - mtx_lock(&fdc->fdc_mtx); - fd->flags &= ~FD_ISADMA; - mtx_unlock(&fdc->fdc_mtx); - } - - /* Unwedge the controller ? */ - if (fdc->flags & FDC_NEEDS_RESET) { - fdc->flags &= ~FDC_NEEDS_RESET; - fdc_reset(fdc); - if (cold) - DELAY(1000000); - else - tsleep(fdc, PRIBIO, "fdcrst", hz); - /* Discard results */ - for (i = 0; i < 4; i++) - fdc_sense_int(fdc, &st0, &cyl); - /* All drives must recal */ - need_recal = 0xf; - } - - /* Pick up a request, if need be wait for it */ - if (fdc->bp == NULL) { - mtx_lock(&fdc->fdc_mtx); - do { - fdc->bp = bioq_takefirst(&fdc->head); - if (fdc->bp == NULL) - msleep(&fdc->head, &fdc->fdc_mtx, - PRIBIO, "-", 0); - } while (fdc->bp == NULL && - (fdc->flags & FDC_KTHREAD_EXIT) == 0); - mtx_unlock(&fdc->fdc_mtx); - - if (fdc->bp == NULL) - /* - * Nothing to do, worker thread has been - * requested to stop. - */ - return (0); - - bp = fdc->bp; - fd = fdc->fd = bp->bio_driver1; - fdc->retry = 0; - fd->fd_ioptr = bp->bio_data; - if (bp->bio_cmd == BIO_FMT) { - i = offsetof(struct fd_formb, fd_formb_cylno(0)); - fd->fd_ioptr += i; - fd->fd_iosize = bp->bio_length - i; - } - } - - /* Select drive, setup params */ - fd_select(fd); - if (fdc->fdct == FDC_ENHANCED) - fddsr_wr(fdc, fd->ft->trans); - else - fdctl_wr(fdc, fd->ft->trans); - - if (bp->bio_cmd == BIO_PROBE) { - if ((!(device_get_flags(fd->dev) & FD_NO_CHLINE) && - !(fdin_rd(fdc) & FDI_DCHG) && - !(fd->flags & FD_EMPTY)) || - fd_probe_disk(fd, &need_recal) == 0) - return (fdc_biodone(fdc, 0)); - return (1); - } - - /* - * If we are dead just flush the requests - */ - if (fd->flags & FD_EMPTY) - return (fdc_biodone(fdc, ENXIO)); - - /* Check if we lost our media */ - if (fdin_rd(fdc) & FDI_DCHG) { - if (debugflags & 0x40) - printf("Lost disk\n"); - mtx_lock(&fdc->fdc_mtx); - fd->flags |= FD_EMPTY; - fd->flags |= FD_NEWDISK; - mtx_unlock(&fdc->fdc_mtx); - g_topology_lock(); - g_orphan_provider(fd->fd_provider, ENXIO); - fd->fd_provider->flags |= G_PF_WITHER; - fd->fd_provider = - g_new_providerf(fd->fd_geom, "%s", fd->fd_geom->name); - g_error_provider(fd->fd_provider, 0); - g_topology_unlock(); - return (fdc_biodone(fdc, ENXIO)); - } - - /* Check if the floppy is write-protected */ - if (bp->bio_cmd == BIO_FMT || bp->bio_cmd == BIO_WRITE) { - retry_line = __LINE__; - if(fdc_sense_drive(fdc, &st3) != 0) - return (1); - if(st3 & NE7_ST3_WP) - return (fdc_biodone(fdc, EROFS)); - } - - mfm = (fd->ft->flags & FL_MFM)? NE7CMD_MFM: 0; - steptrac = (fd->ft->flags & FL_2STEP)? 2: 1; - i = fd->ft->sectrac * fd->ft->heads; - cylinder = bp->bio_pblkno / i; - descyl = cylinder * steptrac; - sec = bp->bio_pblkno % i; - nsect = i - sec; - head = sec / fd->ft->sectrac; - sec = sec % fd->ft->sectrac + 1; - - /* If everything is going swimmingly, use multisector xfer */ - if (fdc->retry == 0 && - (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE)) { - fd->fd_iosize = imin(nsect * fd->sectorsize, bp->bio_resid); - nsect = fd->fd_iosize / fd->sectorsize; - } else if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { - fd->fd_iosize = fd->sectorsize; - nsect = 1; - } - - /* Do RECAL if we need to or are going to track zero anyway */ - if ((need_recal & (1 << fd->fdsu)) || - (cylinder == 0 && fd->track != 0) || - fdc->retry > 2) { - retry_line = __LINE__; - if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fd->fdsu, 0)) - return (1); - tsleep(fdc, PRIBIO, "fdrecal", hz); - retry_line = __LINE__; - if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) - return (1); /* XXX */ - retry_line = __LINE__; - if ((st0 & 0xc0) || cyl != 0) - return (1); - need_recal &= ~(1 << fd->fdsu); - fd->track = 0; - /* let the heads settle */ - if (settle) - tsleep(fdc->fd, PRIBIO, "fdhdstl", settle); - } - - /* - * SEEK to where we want to be - */ - if (cylinder != fd->track) { - retry_line = __LINE__; - if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, descyl, 0)) - return (1); - tsleep(fdc, PRIBIO, "fdseek", hz); - retry_line = __LINE__; - if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) - return (1); /* XXX */ - retry_line = __LINE__; - if ((st0 & 0xc0) || cyl != descyl) { - need_recal |= (1 << fd->fdsu); - return (1); - } - /* let the heads settle */ - if (settle) - tsleep(fdc->fd, PRIBIO, "fdhdstl", settle); - } - fd->track = cylinder; - - if (debugflags & 8) - printf("op %x bn %ju siz %u ptr %p retry %d\n", - bp->bio_cmd, bp->bio_pblkno, fd->fd_iosize, - fd->fd_ioptr, fdc->retry); - - /* Setup ISADMA if we need it and have it */ - if ((bp->bio_cmd == BIO_READ || - bp->bio_cmd == BIO_WRITE || - bp->bio_cmd == BIO_FMT) - && !(fdc->flags & FDC_NODMA)) { - isa_dmastart( - bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE, - fd->fd_ioptr, fd->fd_iosize, fdc->dmachan); - mtx_lock(&fdc->fdc_mtx); - fd->flags |= FD_ISADMA; - mtx_unlock(&fdc->fdc_mtx); - } - - /* Do PIO if we have to */ - if (fdc->flags & FDC_NODMA) { - if (bp->bio_cmd == BIO_READ || - bp->bio_cmd == BIO_WRITE || - bp->bio_cmd == BIO_FMT) - fdbcdr_wr(fdc, 1, fd->fd_iosize); - if (bp->bio_cmd == BIO_WRITE || - bp->bio_cmd == BIO_FMT) - fdc_pio(fdc); - } - - switch(bp->bio_cmd) { - case BIO_FMT: - /* formatting */ - finfo = (struct fd_formb *)bp->bio_data; - retry_line = __LINE__; - if (fdc_cmd(fdc, 6, - NE7CMD_FORMAT | mfm, - head << 2 | fd->fdsu, - finfo->fd_formb_secshift, - finfo->fd_formb_nsecs, - finfo->fd_formb_gaplen, - finfo->fd_formb_fillbyte, 0)) - return (1); - break; - case BIO_RDID: - retry_line = __LINE__; - if (fdc_cmd(fdc, 2, - NE7CMD_READID | mfm, - head << 2 | fd->fdsu, 0)) - return (1); - break; - case BIO_READ: - retry_line = __LINE__; - if (fdc_cmd(fdc, 9, - NE7CMD_READ | NE7CMD_SK | mfm | NE7CMD_MT, - head << 2 | fd->fdsu, /* head & unit */ - fd->track, /* track */ - head, /* head */ - sec, /* sector + 1 */ - fd->ft->secsize, /* sector size */ - fd->ft->sectrac, /* sectors/track */ - fd->ft->gap, /* gap size */ - fd->ft->datalen, /* data length */ - 0)) - return (1); - break; - case BIO_WRITE: - retry_line = __LINE__; - if (fdc_cmd(fdc, 9, - NE7CMD_WRITE | mfm | NE7CMD_MT, - head << 2 | fd->fdsu, /* head & unit */ - fd->track, /* track */ - head, /* head */ - sec, /* sector + 1 */ - fd->ft->secsize, /* sector size */ - fd->ft->sectrac, /* sectors/track */ - fd->ft->gap, /* gap size */ - fd->ft->datalen, /* data length */ - 0)) - return (1); - break; - default: - KASSERT(0 == 1, ("Wrong bio_cmd %x\n", bp->bio_cmd)); - } - - /* Wait for interrupt */ - i = tsleep(fdc, PRIBIO, "fddata", hz); - - /* PIO if the read looks good */ - if (i == 0 && (fdc->flags & FDC_NODMA) && (bp->bio_cmd == BIO_READ)) - fdc_pio(fdc); - - /* Finish DMA */ - if (fd->flags & FD_ISADMA) { - isa_dmadone( - bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE, - fd->fd_ioptr, fd->fd_iosize, fdc->dmachan); - mtx_lock(&fdc->fdc_mtx); - fd->flags &= ~FD_ISADMA; - mtx_unlock(&fdc->fdc_mtx); - } - - if (i != 0) { - /* - * Timeout. - * - * Due to IBM's brain-dead design, the FDC has a faked ready - * signal, hardwired to ready == true. Thus, any command - * issued if there's no diskette in the drive will _never_ - * complete, and must be aborted by resetting the FDC. - * Many thanks, Big Blue! - */ - retry_line = __LINE__; - fdc->flags |= FDC_NEEDS_RESET; - return (1); - } - - retry_line = __LINE__; - if (fdc_read_status(fdc)) - return (1); - - if (debugflags & 0x10) - printf(" -> %x %x %x %x\n", - fdc->status[0], fdc->status[1], - fdc->status[2], fdc->status[3]); - - st0 = fdc->status[0] & NE7_ST0_IC; - if (st0 != 0) { - retry_line = __LINE__; - if (st0 == NE7_ST0_IC_AT && fdc->status[1] & NE7_ST1_OR) { - /* - * DMA overrun. Someone hogged the bus and - * didn't release it in time for the next - * FDC transfer. - */ - return (1); - } - retry_line = __LINE__; - if(st0 == NE7_ST0_IC_IV) { - fdc->flags |= FDC_NEEDS_RESET; - return (1); - } - retry_line = __LINE__; - if(st0 == NE7_ST0_IC_AT && fdc->status[2] & NE7_ST2_WC) { - need_recal |= (1 << fd->fdsu); - return (1); - } - if (debugflags & 0x20) { - printf("status %02x %02x %02x %02x %02x %02x\n", - fdc->status[0], fdc->status[1], fdc->status[2], - fdc->status[3], fdc->status[4], fdc->status[5]); - } - retry_line = __LINE__; - if (fd->options & FDOPT_NOERROR) - override_error = 1; - else - return (1); - } - /* All OK */ - switch(bp->bio_cmd) { - case BIO_RDID: - /* copy out ID field contents */ - idp = (struct fdc_readid *)bp->bio_data; - idp->cyl = fdc->status[3]; - idp->head = fdc->status[4]; - idp->sec = fdc->status[5]; - idp->secshift = fdc->status[6]; - if (debugflags & 0x40) - printf("c %d h %d s %d z %d\n", - idp->cyl, idp->head, idp->sec, idp->secshift); - break; - case BIO_READ: - case BIO_WRITE: - bp->bio_pblkno += nsect; - bp->bio_resid -= fd->fd_iosize; - bp->bio_completed += fd->fd_iosize; - fd->fd_ioptr += fd->fd_iosize; - if (override_error) { - if ((debugflags & 4)) - printf("FDOPT_NOERROR: returning bad data\n"); - } else { - /* Since we managed to get something done, - * reset the retry */ - fdc->retry = 0; - if (bp->bio_resid > 0) - return (0); - } - break; - case BIO_FMT: - break; - } - return (fdc_biodone(fdc, 0)); -} - -static void -fdc_thread(void *arg) -{ - struct fdc_data *fdc; - - fdc = arg; - int i; - - mtx_lock(&fdc->fdc_mtx); - fdc->flags |= FDC_KTHREAD_ALIVE; - while ((fdc->flags & FDC_KTHREAD_EXIT) == 0) { - mtx_unlock(&fdc->fdc_mtx); - i = fdc_worker(fdc); - if (i && debugflags & 0x20) { - if (fdc->bp != NULL) { - g_print_bio(fdc->bp); - printf("\n"); - } - printf("Retry line %d\n", retry_line); - } - fdc->retry += i; - mtx_lock(&fdc->fdc_mtx); - } - fdc->flags &= ~(FDC_KTHREAD_EXIT | FDC_KTHREAD_ALIVE); - mtx_unlock(&fdc->fdc_mtx); - - kproc_exit(0); -} - -/* - * Enqueue a request. - */ -static void -fd_enqueue(struct fd_data *fd, struct bio *bp) -{ - struct fdc_data *fdc; - int call; - - call = 0; - fdc = fd->fdc; - mtx_lock(&fdc->fdc_mtx); - /* If we go from idle, cancel motor turnoff */ - if (fd->fd_iocount++ == 0) - callout_stop(&fd->toffhandle); - if (fd->flags & FD_MOTOR) { - /* The motor is on, send it directly to the controller */ - bioq_disksort(&fdc->head, bp); - wakeup(&fdc->head); - } else { - /* Queue it on the drive until the motor has started */ - bioq_insert_tail(&fd->fd_bq, bp); - if (!(fd->flags & FD_MOTORWAIT)) - fd_motor(fd, 1); - } - mtx_unlock(&fdc->fdc_mtx); -} - -/* - * Try to find out if we have a disk in the drive. - */ -static int -fd_probe_disk(struct fd_data *fd, int *recal) -{ - struct fdc_data *fdc; - int st0, st3, cyl; - int oopts, ret; - - fdc = fd->fdc; - oopts = fd->options; - fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY; - ret = 1; - - /* - * First recal, then seek to cyl#1, this clears the old condition on - * the disk change line so we can examine it for current status. - */ - if (debugflags & 0x40) - printf("New disk in probe\n"); - mtx_lock(&fdc->fdc_mtx); - fd->flags |= FD_NEWDISK; - mtx_unlock(&fdc->fdc_mtx); - if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fd->fdsu, 0)) - goto done; - tsleep(fdc, PRIBIO, "fdrecal", hz); - if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) - goto done; /* XXX */ - if ((st0 & 0xc0) || cyl != 0) - goto done; - - /* Seek to track 1 */ - if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, 1, 0)) - goto done; - tsleep(fdc, PRIBIO, "fdseek", hz); - if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) - goto done; /* XXX */ - *recal |= (1 << fd->fdsu); - if (fdin_rd(fdc) & FDI_DCHG) { - if (debugflags & 0x40) - printf("Empty in probe\n"); - mtx_lock(&fdc->fdc_mtx); - fd->flags |= FD_EMPTY; - mtx_unlock(&fdc->fdc_mtx); - } else { - if (fdc_sense_drive(fdc, &st3) != 0) - goto done; - if (debugflags & 0x40) - printf("Got disk in probe\n"); - mtx_lock(&fdc->fdc_mtx); - fd->flags &= ~FD_EMPTY; - if (st3 & NE7_ST3_WP) - fd->flags |= FD_WP; - else - fd->flags &= ~FD_WP; - mtx_unlock(&fdc->fdc_mtx); - } - ret = 0; - -done: - fd->options = oopts; - return (ret); -} - -static int -fdmisccmd(struct fd_data *fd, u_int cmd, void *data) -{ - struct bio *bp; - struct fd_formb *finfo; - struct fdc_readid *idfield; - int error; - - bp = malloc(sizeof(struct bio), M_TEMP, M_WAITOK | M_ZERO); - - /* - * Set up a bio request for fdstrategy(). bio_offset is faked - * so that fdstrategy() will seek to the requested - * cylinder, and use the desired head. - */ - bp->bio_cmd = cmd; - if (cmd == BIO_FMT) { - finfo = (struct fd_formb *)data; - bp->bio_pblkno = - (finfo->cyl * fd->ft->heads + finfo->head) * - fd->ft->sectrac; - bp->bio_length = sizeof *finfo; - } else if (cmd == BIO_RDID) { - idfield = (struct fdc_readid *)data; - bp->bio_pblkno = - (idfield->cyl * fd->ft->heads + idfield->head) * - fd->ft->sectrac; - bp->bio_length = sizeof(struct fdc_readid); - } else if (cmd == BIO_PROBE) { - /* nothing */ - } else - panic("wrong cmd in fdmisccmd()"); - bp->bio_offset = bp->bio_pblkno * fd->sectorsize; - bp->bio_data = data; - bp->bio_driver1 = fd; - bp->bio_flags = 0; - - fd_enqueue(fd, bp); - - do { - tsleep(bp, PRIBIO, "fdwait", hz); - } while (!(bp->bio_flags & BIO_DONE)); - error = bp->bio_error; - - free(bp, M_TEMP); - return (error); -} - -/* - * Try figuring out the density of the media present in our device. - */ -static int -fdautoselect(struct fd_data *fd) -{ - struct fd_type *fdtp; - struct fdc_readid id; - int oopts, rv; - - if (!(fd->ft->flags & FL_AUTO)) - return (0); - - fdtp = fd_native_types[fd->type]; - fdsettype(fd, fdtp); - if (!(fd->ft->flags & FL_AUTO)) - return (0); - - /* - * Try reading sector ID fields, first at cylinder 0, head 0, - * then at cylinder 2, head N. We don't probe cylinder 1, - * since for 5.25in DD media in a HD drive, there are no data - * to read (2 step pulses per media cylinder required). For - * two-sided media, the second probe always goes to head 1, so - * we can tell them apart from single-sided media. As a - * side-effect this means that single-sided media should be - * mentioned in the search list after two-sided media of an - * otherwise identical density. Media with a different number - * of sectors per track but otherwise identical parameters - * cannot be distinguished at all. - * - * If we successfully read an ID field on both cylinders where - * the recorded values match our expectation, we are done. - * Otherwise, we try the next density entry from the table. - * - * Stepping to cylinder 2 has the side-effect of clearing the - * unit attention bit. - */ - oopts = fd->options; - fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY; - for (; fdtp->heads; fdtp++) { - fdsettype(fd, fdtp); - - id.cyl = id.head = 0; - rv = fdmisccmd(fd, BIO_RDID, &id); - if (rv != 0) - continue; - if (id.cyl != 0 || id.head != 0 || id.secshift != fdtp->secsize) - continue; - id.cyl = 2; - id.head = fd->ft->heads - 1; - rv = fdmisccmd(fd, BIO_RDID, &id); - if (id.cyl != 2 || id.head != fdtp->heads - 1 || - id.secshift != fdtp->secsize) - continue; - if (rv == 0) - break; - } - - fd->options = oopts; - if (fdtp->heads == 0) { - if (debugflags & 0x40) - device_printf(fd->dev, "autoselection failed\n"); - fdsettype(fd, fd_native_types[fd->type]); - return (-1); - } else { - if (debugflags & 0x40) { - device_printf(fd->dev, - "autoselected %d KB medium\n", - fd->ft->size / 2); - fdprinttype(fd->ft); - } - return (0); - } -} - -/* - * GEOM class implementation - */ - -static g_access_t fd_access; -static g_start_t fd_start; -static g_ioctl_t fd_ioctl; - -struct g_class g_fd_class = { - .name = "FD", - .version = G_VERSION, - .start = fd_start, - .access = fd_access, - .ioctl = fd_ioctl, -}; - -static int -fd_access(struct g_provider *pp, int r, int w, int e) -{ - struct fd_data *fd; - struct fdc_data *fdc; - int ar, aw, ae; - int busy; - - fd = pp->geom->softc; - fdc = fd->fdc; - - /* - * If our provider is withering, we can only get negative requests - * and we don't want to even see them - */ - if (pp->flags & G_PF_WITHER) - return (0); - - ar = r + pp->acr; - aw = w + pp->acw; - ae = e + pp->ace; - - if (ar == 0 && aw == 0 && ae == 0) { - fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR); - device_unbusy(fd->dev); - return (0); - } - - busy = 0; - if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) { - if (fdmisccmd(fd, BIO_PROBE, NULL)) - return (ENXIO); - if (fd->flags & FD_EMPTY) - return (ENXIO); - if (fd->flags & FD_NEWDISK) { - if (fdautoselect(fd) != 0 && - (device_get_flags(fd->dev) & FD_NO_CHLINE)) { - mtx_lock(&fdc->fdc_mtx); - fd->flags |= FD_EMPTY; - mtx_unlock(&fdc->fdc_mtx); - return (ENXIO); - } - mtx_lock(&fdc->fdc_mtx); - fd->flags &= ~FD_NEWDISK; - mtx_unlock(&fdc->fdc_mtx); - } - device_busy(fd->dev); - busy = 1; - } - - if (w > 0 && (fd->flags & FD_WP)) { - if (busy) - device_unbusy(fd->dev); - return (EROFS); - } - - pp->sectorsize = fd->sectorsize; - pp->stripesize = fd->ft->heads * fd->ft->sectrac * fd->sectorsize; - pp->mediasize = pp->stripesize * fd->ft->tracks; - return (0); -} - -static void -fd_start(struct bio *bp) -{ - struct fdc_data * fdc; - struct fd_data * fd; - - fd = bp->bio_to->geom->softc; - fdc = fd->fdc; - bp->bio_driver1 = fd; - if (bp->bio_cmd == BIO_GETATTR) { - if (g_handleattr_int(bp, "GEOM::fwsectors", fd->ft->sectrac)) - return; - if (g_handleattr_int(bp, "GEOM::fwheads", fd->ft->heads)) - return; - g_io_deliver(bp, ENOIOCTL); - return; - } - if (!(bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE)) { - g_io_deliver(bp, EOPNOTSUPP); - return; - } - bp->bio_pblkno = bp->bio_offset / fd->sectorsize; - bp->bio_resid = bp->bio_length; - fd_enqueue(fd, bp); - return; -} - -static int -fd_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) -{ - struct fd_data *fd; - struct fdc_status *fsp; - struct fdc_readid *rid; - int error; - - fd = pp->geom->softc; - - switch (cmd) { - case FD_GTYPE: /* get drive type */ - *(struct fd_type *)data = *fd->ft; - return (0); - - case FD_STYPE: /* set drive type */ - /* - * Allow setting drive type temporarily iff - * currently unset. Used for fdformat so any - * user can set it, and then start formatting. - */ - fd->fts = *(struct fd_type *)data; - if (fd->fts.sectrac) { - /* XXX: check for rubbish */ - fdsettype(fd, &fd->fts); - } else { - fdsettype(fd, fd_native_types[fd->type]); - } - if (debugflags & 0x40) - fdprinttype(fd->ft); - return (0); - - case FD_GOPTS: /* get drive options */ - *(int *)data = fd->options; - return (0); - - case FD_SOPTS: /* set drive options */ - fd->options = *(int *)data; - return (0); - - case FD_CLRERR: - error = priv_check(td, PRIV_DRIVER); - if (error) - return (error); - fd->fdc->fdc_errs = 0; - return (0); - - case FD_GSTAT: - fsp = (struct fdc_status *)data; - if ((fd->fdc->flags & FDC_STAT_VALID) == 0) - return (EINVAL); - memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int)); - return (0); - - case FD_GDTYPE: - *(enum fd_drivetype *)data = fd->type; - return (0); - - case FD_FORM: - if (!(fflag & FWRITE)) - return (EPERM); - if (((struct fd_formb *)data)->format_version != - FD_FORMAT_VERSION) - return (EINVAL); /* wrong version of formatting prog */ - error = fdmisccmd(fd, BIO_FMT, data); - mtx_lock(&fd->fdc->fdc_mtx); - fd->flags |= FD_NEWDISK; - mtx_unlock(&fd->fdc->fdc_mtx); - break; - - case FD_READID: - rid = (struct fdc_readid *)data; - if (rid->cyl > 85 || rid->head > 1) - return (EINVAL); - error = fdmisccmd(fd, BIO_RDID, data); - break; - - case FIONBIO: - case FIOASYNC: - /* For backwards compat with old fd*(8) tools */ - error = 0; - break; - - default: - if (debugflags & 0x80) - printf("Unknown ioctl %lx\n", cmd); - error = ENOIOCTL; - break; - } - return (error); -}; - - - -/* - * Configuration/initialization stuff, per controller. - */ - -devclass_t fdc_devclass; -static devclass_t fd_devclass; - -struct fdc_ivars { - int fdunit; - int fdtype; -}; - -void -fdc_release_resources(struct fdc_data *fdc) -{ - device_t dev; - struct resource *last; - int i; - - dev = fdc->fdc_dev; - if (fdc->fdc_intr) - bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr); - fdc->fdc_intr = NULL; - if (fdc->res_irq != NULL) - bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, - fdc->res_irq); - fdc->res_irq = NULL; - last = NULL; - for (i = 0; i < FDC_MAXREG; i++) { - if (fdc->resio[i] != NULL && fdc->resio[i] != last) { - bus_release_resource(dev, SYS_RES_IOPORT, - fdc->ridio[i], fdc->resio[i]); - last = fdc->resio[i]; - fdc->resio[i] = NULL; - } - } - if (fdc->res_drq != NULL) - bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, - fdc->res_drq); - fdc->res_drq = NULL; -} - -int -fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) -{ - struct fdc_ivars *ivars = device_get_ivars(child); - - switch (which) { - case FDC_IVAR_FDUNIT: - *result = ivars->fdunit; - break; - case FDC_IVAR_FDTYPE: - *result = ivars->fdtype; - break; - default: - return (ENOENT); - } - return (0); -} - -int -fdc_write_ivar(device_t dev, device_t child, int which, uintptr_t value) -{ - struct fdc_ivars *ivars = device_get_ivars(child); - - switch (which) { - case FDC_IVAR_FDUNIT: - ivars->fdunit = value; - break; - case FDC_IVAR_FDTYPE: - ivars->fdtype = value; - break; - default: - return (ENOENT); - } - return (0); -} - -int -fdc_initial_reset(device_t dev, struct fdc_data *fdc) -{ - int ic_type, part_id; - - /* - * A status value of 0xff is very unlikely, but not theoretically - * impossible, but it is far more likely to indicate an empty bus. - */ - if (fdsts_rd(fdc) == 0xff) - return (ENXIO); - - /* - * Assert a reset to the floppy controller and check that the status - * register goes to zero. - */ - fdout_wr(fdc, 0); - fdout_wr(fdc, 0); - if (fdsts_rd(fdc) != 0) - return (ENXIO); - - /* - * Clear the reset and see it come ready. - */ - fdout_wr(fdc, FDO_FRST); - DELAY(100); - if (fdsts_rd(fdc) != 0x80) - return (ENXIO); - - /* Then, see if it can handle a command. */ - if (fdc_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(6, 240), - NE7_SPEC_2(31, 0), 0)) - return (ENXIO); - - /* - * Try to identify the chip. - * - * The i8272 datasheet documents that unknown commands - * will return ST0 as 0x80. The i8272 is supposedly identical - * to the NEC765. - * The i82077SL datasheet says 0x90 for the VERSION command, - * and several "superio" chips emulate this. - */ - if (fdc_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type)) - return (ENXIO); - if (fdc_cmd(fdc, 1, 0x18, 1, &part_id)) - return (ENXIO); - if (bootverbose) - device_printf(dev, - "ic_type %02x part_id %02x\n", ic_type, part_id); - switch (ic_type & 0xff) { - case 0x80: - device_set_desc(dev, "NEC 765 or clone"); - fdc->fdct = FDC_NE765; - break; - case 0x81: - case 0x90: - device_set_desc(dev, - "Enhanced floppy controller"); - fdc->fdct = FDC_ENHANCED; - break; - default: - device_set_desc(dev, "Generic floppy controller"); - fdc->fdct = FDC_UNKNOWN; - break; - } - return (0); -} - -int -fdc_detach(device_t dev) -{ - struct fdc_data *fdc; - int error; - - fdc = device_get_softc(dev); - - /* have our children detached first */ - if ((error = bus_generic_detach(dev))) - return (error); - - if (fdc->fdc_intr) - bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr); - fdc->fdc_intr = NULL; - - /* kill worker thread */ - mtx_lock(&fdc->fdc_mtx); - fdc->flags |= FDC_KTHREAD_EXIT; - wakeup(&fdc->head); - while ((fdc->flags & FDC_KTHREAD_ALIVE) != 0) - msleep(fdc->fdc_thread, &fdc->fdc_mtx, PRIBIO, "fdcdet", 0); - mtx_unlock(&fdc->fdc_mtx); - - /* reset controller, turn motor off */ - fdout_wr(fdc, 0); - - if (!(fdc->flags & FDC_NODMA)) - isa_dma_release(fdc->dmachan); - fdc_release_resources(fdc); - mtx_destroy(&fdc->fdc_mtx); - return (0); -} - -/* - * Add a child device to the fdc controller. It will then be probed etc. - */ -device_t -fdc_add_child(device_t dev, const char *name, int unit) -{ - struct fdc_ivars *ivar; - device_t child; - - ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO); - if (ivar == NULL) - return (NULL); - child = device_add_child(dev, name, unit); - if (child == NULL) { - free(ivar, M_DEVBUF); - return (NULL); - } - device_set_ivars(child, ivar); - ivar->fdunit = unit; - ivar->fdtype = FDT_NONE; - if (resource_disabled(name, unit)) - device_disable(child); - return (child); -} - -int -fdc_attach(device_t dev) -{ - struct fdc_data *fdc; - int error; - - fdc = device_get_softc(dev); - fdc->fdc_dev = dev; - error = fdc_initial_reset(dev, fdc); - if (error) { - device_printf(dev, "does not respond\n"); - return (error); - } - error = bus_setup_intr(dev, fdc->res_irq, - INTR_TYPE_BIO | INTR_ENTROPY | - ((fdc->flags & FDC_NOFAST) ? INTR_MPSAFE : 0), - ((fdc->flags & FDC_NOFAST) ? NULL : fdc_intr_fast), - ((fdc->flags & FDC_NOFAST) ? fdc_intr : NULL), - fdc, &fdc->fdc_intr); - if (error) { - device_printf(dev, "cannot setup interrupt\n"); - return (error); - } - if (!(fdc->flags & FDC_NODMA)) { - error = isa_dma_acquire(fdc->dmachan); - if (!error) { - error = isa_dma_init(fdc->dmachan, - MAX_BYTES_PER_CYL, M_WAITOK); - if (error) - isa_dma_release(fdc->dmachan); - } - if (error) - return (error); - } - fdc->fdcu = device_get_unit(dev); - fdc->flags |= FDC_NEEDS_RESET; - - mtx_init(&fdc->fdc_mtx, "fdc lock", NULL, MTX_DEF); - - /* reset controller, turn motor off, clear fdout mirror reg */ - fdout_wr(fdc, fdc->fdout = 0); - bioq_init(&fdc->head); - - settle = hz / 8; - - return (0); -} - -void -fdc_start_worker(device_t dev) -{ - struct fdc_data *fdc; - - fdc = device_get_softc(dev); - kproc_create(fdc_thread, fdc, &fdc->fdc_thread, 0, 0, - "fdc%d", device_get_unit(dev)); -} - -int -fdc_hints_probe(device_t dev) -{ - const char *name, *dname; - int i, error, dunit; - - /* - * Probe and attach any children. We should probably detect - * devices from the BIOS unless overridden. - */ - name = device_get_nameunit(dev); - i = 0; - while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) { - resource_int_value(dname, dunit, "drive", &dunit); - fdc_add_child(dev, dname, dunit); - } - - if ((error = bus_generic_attach(dev)) != 0) - return (error); - return (0); -} - -int -fdc_print_child(device_t me, device_t child) -{ - int retval = 0, flags; - - retval += bus_print_child_header(me, child); - retval += printf(" on %s drive %d", device_get_nameunit(me), - fdc_get_fdunit(child)); - if ((flags = device_get_flags(me)) != 0) - retval += printf(" flags %#x", flags); - retval += printf("\n"); - - return (retval); -} - -/* - * Configuration/initialization, per drive. - */ -static int -fd_probe(device_t dev) -{ - int unit; - int i; - u_int st0, st3; - struct fd_data *fd; - struct fdc_data *fdc; - int fdsu; - int flags, type; - - fdsu = fdc_get_fdunit(dev); - fd = device_get_softc(dev); - fdc = device_get_softc(device_get_parent(dev)); - flags = device_get_flags(dev); - - fd->dev = dev; - fd->fdc = fdc; - fd->fdsu = fdsu; - unit = device_get_unit(dev); - - /* Auto-probe if fdinfo is present, but always allow override. */ - type = flags & FD_TYPEMASK; - if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) { - fd->type = type; - goto done; - } else { - /* make sure fdautoselect() will be called */ - fd->flags = FD_EMPTY; - fd->type = type; - } - -#if defined(__i386__) || defined(__amd64__) - if (fd->type == FDT_NONE && (unit == 0 || unit == 1)) { - /* Look up what the BIOS thinks we have. */ - if (unit == 0) - fd->type = (rtcin(RTC_FDISKETTE) & 0xf0) >> 4; - else - fd->type = rtcin(RTC_FDISKETTE) & 0x0f; - if (fd->type == FDT_288M_1) - fd->type = FDT_288M; - } -#endif /* __i386__ || __amd64__ */ - /* is there a unit? */ - if (fd->type == FDT_NONE) - return (ENXIO); - - mtx_lock(&fdc->fdc_mtx); - - /* select it */ - fd_select(fd); - fd_motor(fd, 1); - fdc->fd = fd; - fdc_reset(fdc); /* XXX reset, then unreset, etc. */ - DELAY(1000000); /* 1 sec */ - - if ((flags & FD_NO_PROBE) == 0) { - /* If we're at track 0 first seek inwards. */ - if ((fdc_sense_drive(fdc, &st3) == 0) && - (st3 & NE7_ST3_T0)) { - /* Seek some steps... */ - if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { - /* ...wait a moment... */ - DELAY(300000); - /* make ctrlr happy: */ - fdc_sense_int(fdc, NULL, NULL); - } - } - - for (i = 0; i < 2; i++) { - /* - * we must recalibrate twice, just in case the - * heads have been beyond cylinder 76, since - * most FDCs still barf when attempting to - * recalibrate more than 77 steps - */ - /* go back to 0: */ - if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) { - /* a second being enough for full stroke seek*/ - DELAY(i == 0 ? 1000000 : 300000); - - /* anything responding? */ - if (fdc_sense_int(fdc, &st0, NULL) == 0 && - (st0 & NE7_ST0_EC) == 0) - break; /* already probed successfully */ - } - } - } - - fd_motor(fd, 0); - fdc->fd = NULL; - mtx_unlock(&fdc->fdc_mtx); - - if ((flags & FD_NO_PROBE) == 0 && - (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */ - return (ENXIO); - -done: - - switch (fd->type) { - case FDT_12M: - device_set_desc(dev, "1200-KB 5.25\" drive"); - break; - case FDT_144M: - device_set_desc(dev, "1440-KB 3.5\" drive"); - break; - case FDT_288M: - device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)"); - break; - case FDT_360K: - device_set_desc(dev, "360-KB 5.25\" drive"); - break; - case FDT_720K: - device_set_desc(dev, "720-KB 3.5\" drive"); - break; - default: - return (ENXIO); - } - fd->track = FD_NO_TRACK; - fd->fdc = fdc; - fd->fdsu = fdsu; - fd->options = 0; - callout_init_mtx(&fd->toffhandle, &fd->fdc->fdc_mtx, 0); - - /* initialize densities for subdevices */ - fdsettype(fd, fd_native_types[fd->type]); - return (0); -} - -/* - * We have to do this in a geom event because GEOM is not running - * when fd_attach() is. - * XXX: move fd_attach after geom like ata/scsi disks - */ -static void -fd_attach2(void *arg, int flag) -{ - struct fd_data *fd; - - fd = arg; - - fd->fd_geom = g_new_geomf(&g_fd_class, - "fd%d", device_get_unit(fd->dev)); - fd->fd_provider = g_new_providerf(fd->fd_geom, "%s", fd->fd_geom->name); - fd->fd_geom->softc = fd; - g_error_provider(fd->fd_provider, 0); -} - -static int -fd_attach(device_t dev) -{ - struct fd_data *fd; - - fd = device_get_softc(dev); - g_post_event(fd_attach2, fd, M_WAITOK, NULL); - fd->flags |= FD_EMPTY; - bioq_init(&fd->fd_bq); - - return (0); -} - -static void -fd_detach_geom(void *arg, int flag) -{ - struct fd_data *fd = arg; - - g_topology_assert(); - g_wither_geom(fd->fd_geom, ENXIO); -} - -static int -fd_detach(device_t dev) -{ - struct fd_data *fd; - - fd = device_get_softc(dev); - g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL); - while (device_get_state(dev) == DS_BUSY) - tsleep(fd, PZERO, "fdd", hz/10); - callout_drain(&fd->toffhandle); - - return (0); -} - -static device_method_t fd_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fd_probe), - DEVMETHOD(device_attach, fd_attach), - DEVMETHOD(device_detach, fd_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */ - DEVMETHOD(device_resume, bus_generic_resume), /* XXX */ - { 0, 0 } -}; - -static driver_t fd_driver = { - "fd", - fd_methods, - sizeof(struct fd_data) -}; - -static int -fdc_modevent(module_t mod, int type, void *data) -{ - - return (g_modevent(NULL, type, &g_fd_class)); -} - -DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, fdc_modevent, 0); Index: sys/dev/fdc/fdc_acpi.c =================================================================== --- sys/dev/fdc/fdc_acpi.c +++ /dev/null @@ -1,274 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2004 Nate Lawson (SDG) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -static int fdc_acpi_probe(device_t dev); -static int fdc_acpi_attach(device_t dev); -static int fdc_acpi_probe_children(device_t bus, device_t dev, - void *fde); -static ACPI_STATUS fdc_acpi_probe_child(ACPI_HANDLE h, device_t *dev, - int level, void *arg); - -/* Maximum number of child devices of a controller (4 floppy + 1 tape.) */ -#define ACPI_FDC_MAXDEVS 5 - -/* Standard size of buffer returned by the _FDE method. */ -#define ACPI_FDC_FDE_LEN (ACPI_FDC_MAXDEVS * sizeof(uint32_t)) - -/* - * Parameters for the tape drive (5th device). Some BIOS authors use this - * for all drives, not just the tape drive (e.g., ASUS K8V). This isn't - * grossly incompatible with the spec since it says the first four devices - * are simple booleans. - */ -#define ACPI_FD_UNKNOWN 0 -#define ACPI_FD_PRESENT 1 -#define ACPI_FD_NEVER_PRESENT 2 - -/* Temporary buf length for evaluating _FDE and _FDI. */ -#define ACPI_FDC_BUFLEN 1024 - -/* Context for walking FDC child devices. */ -struct fdc_walk_ctx { - uint32_t fd_present[ACPI_FDC_MAXDEVS]; - int index; - device_t acpi_dev; - device_t dev; -}; - -static int -fdc_acpi_probe(device_t dev) -{ - device_t bus; - static char *fdc_ids[] = { "PNP0700", "PNP0701", NULL }; - - bus = device_get_parent(dev); - if (ACPI_ID_PROBE(bus, dev, fdc_ids) == NULL) - return (ENXIO); - - if (ACPI_SUCCESS(ACPI_EVALUATE_OBJECT(bus, dev, "_FDE", NULL, NULL))) - device_set_desc(dev, "floppy drive controller (FDE)"); - else - device_set_desc(dev, "floppy drive controller"); - return (0); -} - -static int -fdc_acpi_attach(device_t dev) -{ - struct fdc_data *sc; - ACPI_BUFFER buf; - ACPI_OBJECT *obj; - device_t bus; - int error; - - /* Get our softc and use the same accessor as ISA. */ - sc = device_get_softc(dev); - sc->fdc_dev = dev; - - /* Initialize variables and get a temporary buffer for _FDE. */ - error = ENXIO; - buf.Length = ACPI_FDC_BUFLEN; - buf.Pointer = malloc(buf.Length, M_TEMP, M_NOWAIT | M_ZERO); - if (buf.Pointer == NULL) - goto out; - - /* Allocate resources the same as the ISA attachment. */ - error = fdc_isa_alloc_resources(dev, sc); - if (error != 0) - goto out; - - /* Call common attach code in fdc(4) first. */ - error = fdc_attach(dev); - if (error != 0) - goto out; - - /* - * Enumerate _FDE, which lists floppy drives that are present. If - * this fails, fall back to the ISA hints-based probe method. - */ - bus = device_get_parent(dev); - if (ACPI_FAILURE(ACPI_EVALUATE_OBJECT(bus, dev, "_FDE", NULL, &buf))) { - error = fdc_hints_probe(dev); - goto out; - } - - /* Add fd child devices as specified. */ - obj = buf.Pointer; - error = fdc_acpi_probe_children(bus, dev, obj->Buffer.Pointer); - -out: - if (buf.Pointer) - free(buf.Pointer, M_TEMP); - if (error != 0) - fdc_release_resources(sc); - else - fdc_start_worker(dev); - - return (error); -} - -static int -fdc_acpi_probe_children(device_t bus, device_t dev, void *fde) -{ - struct fdc_walk_ctx *ctx; - devclass_t fd_dc; - int i; - - /* Setup the context and walk all child devices. */ - ctx = malloc(sizeof(struct fdc_walk_ctx), M_TEMP, M_NOWAIT); - if (ctx == NULL) { - device_printf(dev, "no memory for walking children\n"); - return (ENOMEM); - } - bcopy(fde, ctx->fd_present, sizeof(ctx->fd_present)); - ctx->index = 0; - ctx->dev = dev; - ctx->acpi_dev = bus; - ACPI_SCAN_CHILDREN(ctx->acpi_dev, dev, 1, fdc_acpi_probe_child, - ctx); - - /* Add any devices not represented by an AML Device handle/node. */ - fd_dc = devclass_find("fd"); - for (i = 0; i < ACPI_FDC_MAXDEVS; i++) - if (ctx->fd_present[i] == ACPI_FD_PRESENT && - devclass_get_device(fd_dc, i) == NULL) { - if (fdc_add_child(dev, "fd", i) == NULL) - device_printf(dev, "fd add failed\n"); - } - free(ctx, M_TEMP); - - /* Attach any children found during the probe. */ - return (bus_generic_attach(dev)); -} - -static ACPI_STATUS -fdc_acpi_probe_child(ACPI_HANDLE h, device_t *dev, int level, void *arg) -{ - struct fdc_walk_ctx *ctx; - device_t child, old_child; - ACPI_BUFFER buf; - ACPI_OBJECT *pkg, *obj; - ACPI_STATUS status; - - ctx = (struct fdc_walk_ctx *)arg; - buf.Pointer = NULL; - - /* - * The first four ints are booleans that indicate whether fd0-3 are - * present or not. The last is for a tape device, which we don't - * bother supporting for now. - */ - if (ctx->index > 3) - return (AE_OK); - - /* This device is not present, move on to the next. */ - if (ctx->fd_present[ctx->index] != ACPI_FD_PRESENT) - goto out; - - /* Create a device for the child with the given index. */ - child = fdc_add_child(ctx->dev, "fd", ctx->index); - if (child == NULL) - goto out; - old_child = *dev; - *dev = child; - - /* Get temporary buffer for _FDI probe. */ - buf.Length = ACPI_FDC_BUFLEN; - buf.Pointer = malloc(buf.Length, M_TEMP, M_NOWAIT | M_ZERO); - if (buf.Pointer == NULL) - goto out; - - /* - * Evaluate _FDI to get drive type to pass to the child. We use the - * old child here since it has a valid ACPI_HANDLE since it is a - * child of acpi. A better way to implement this would be to make fdc - * support the ACPI handle ivar for its children. - */ - status = ACPI_EVALUATE_OBJECT(ctx->acpi_dev, old_child, "_FDI", NULL, - &buf); - if (ACPI_FAILURE(status)) { - if (status != AE_NOT_FOUND) - device_printf(ctx->dev, "_FDI failed - %#x\n", status); - goto out; - } - pkg = (ACPI_OBJECT *)buf.Pointer; - if (!ACPI_PKG_VALID(pkg, 16)) { - device_printf(ctx->dev, "invalid _FDI package\n"); - goto out; - } - obj = &pkg->Package.Elements[1]; - if (obj == NULL || obj->Type != ACPI_TYPE_INTEGER) { - device_printf(ctx->dev, "invalid type object in _FDI\n"); - goto out; - } - fdc_set_fdtype(child, obj->Integer.Value); - -out: - ctx->index++; - if (buf.Pointer) - free(buf.Pointer, M_TEMP); - return (AE_OK); -} - -static device_method_t fdc_acpi_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fdc_acpi_probe), - DEVMETHOD(device_attach, fdc_acpi_attach), - DEVMETHOD(device_detach, fdc_detach), - - /* Bus interface */ - DEVMETHOD(bus_print_child, fdc_print_child), - DEVMETHOD(bus_read_ivar, fdc_read_ivar), - DEVMETHOD(bus_write_ivar, fdc_write_ivar), - - DEVMETHOD_END -}; - -static driver_t fdc_acpi_driver = { - "fdc", - fdc_acpi_methods, - sizeof(struct fdc_data) -}; - -DRIVER_MODULE(fdc, acpi, fdc_acpi_driver, fdc_devclass, 0, 0); Index: sys/dev/fdc/fdc_isa.c =================================================================== --- sys/dev/fdc/fdc_isa.c +++ /dev/null @@ -1,226 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2004-2005 M. Warner Losh. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -static int fdc_isa_probe(device_t); - -static struct isa_pnp_id fdc_ids[] = { - {0x0007d041, "PC standard floppy controller"}, /* PNP0700 */ - {0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */ - {0} -}; - -/* - * On standard ISA, we don't just use an 8 port range - * (e.g. 0x3f0-0x3f7) since that covers an IDE control register at - * 0x3f6. So, on older hardware, we use 0x3f0-0x3f5 and 0x3f7. - * However, some BIOSs omit the control port, while others start at - * 0x3f2. Of the latter, sometimes we have two resources, other times - * we have one. We have to deal with the following cases: - * - * 1: 0x3f0-0x3f5 # very rare - * 2: 0x3f0 # hints -> 0x3f0-0x3f5,0x3f7 - * 3: 0x3f0-0x3f5,0x3f7 # Most common - * 4: 0x3f2-0x3f5,0x3f7 # Second most common - * 5: 0x3f2-0x3f5 # implies 0x3f7 too. - * 6: 0x3f2-0x3f3,0x3f4-0x3f5,0x3f7 # becoming common - * 7: 0x3f2-0x3f3,0x3f4-0x3f5 # rare - * 8: 0x3f0-0x3f1,0x3f2-0x3f3,0x3f4-0x3f5,0x3f7 - * 9: 0x3f0-0x3f3,0x3f4-0x3f5,0x3f7 - * - * The following code is generic for any value of 0x3fx. It is also - * generic for all the above cases, as well as cases where things are - * even weirder. - */ -int -fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc) -{ - struct resource *res; - int i, j, rid, newrid, nport; - u_long port; - - fdc->fdc_dev = dev; - rid = 0; - for (i = 0; i < FDC_MAXREG; i++) - fdc->resio[i] = NULL; - - nport = isa_get_logicalid(dev) ? 1 : 6; - for (rid = 0; ; rid++) { - newrid = rid; - res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &newrid, - rid == 0 ? nport : 1, RF_ACTIVE); - if (res == NULL) - break; - /* - * Mask off the upper bits of the register, and sanity - * check resource ranges. - */ - i = rman_get_start(res) & 0x7; - if (i + rman_get_size(res) - 1 > FDC_MAXREG) { - bus_release_resource(dev, SYS_RES_IOPORT, newrid, res); - return (ENXIO); - } - for (j = 0; j < rman_get_size(res); j++) { - fdc->resio[i + j] = res; - fdc->ridio[i + j] = newrid; - fdc->ioff[i + j] = j; - fdc->ioh[i + j] = rman_get_bushandle(res); - } - } - if (fdc->resio[2] == NULL) { - device_printf(dev, "No FDOUT register!\n"); - return (ENXIO); - } - fdc->iot = rman_get_bustag(fdc->resio[2]); - if (fdc->resio[7] == NULL) { - port = (rman_get_start(fdc->resio[2]) & ~0x7) + 7; - newrid = rid; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &newrid, port, - port, 1, RF_ACTIVE); - if (res == NULL) { - device_printf(dev, "Faking up FDCTL\n"); - fdc->resio[7] = fdc->resio[2]; - fdc->ridio[7] = fdc->ridio[2]; - fdc->ioff[7] = fdc->ioff[2] + 5; - fdc->ioh[7] = fdc->ioh[2]; - } else { - fdc->resio[7] = res; - fdc->ridio[7] = newrid; - fdc->ioff[7] = rman_get_start(res) & 7; - fdc->ioh[7] = rman_get_bushandle(res); - } - } - - fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq, - RF_ACTIVE | RF_SHAREABLE); - if (fdc->res_irq == NULL) { - device_printf(dev, "cannot reserve interrupt line\n"); - return (ENXIO); - } - - if ((fdc->flags & FDC_NODMA) == 0) { - fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, - &fdc->rid_drq, RF_ACTIVE | RF_SHAREABLE); - if (fdc->res_drq == NULL) { - device_printf(dev, "cannot reserve DMA request line\n"); - /* This is broken and doesn't work for ISA case */ - fdc->flags |= FDC_NODMA; - } else - fdc->dmachan = rman_get_start(fdc->res_drq); - } - - return (0); -} - -static int -fdc_isa_probe(device_t dev) -{ - int error; - struct fdc_data *fdc; - - fdc = device_get_softc(dev); - fdc->fdc_dev = dev; - - /* Check pnp ids */ - error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids); - if (error == ENXIO) - return (ENXIO); - - /* Attempt to allocate our resources for the duration of the probe */ - error = fdc_isa_alloc_resources(dev, fdc); - if (error == 0) - error = fdc_initial_reset(dev, fdc); - - fdc_release_resources(fdc); - return (error); -} - -static int -fdc_isa_attach(device_t dev) -{ - struct fdc_data *fdc; - int error; - - fdc = device_get_softc(dev); - fdc->fdc_dev = dev; - error = fdc_isa_alloc_resources(dev, fdc); - if (error == 0) - error = fdc_attach(dev); - if (error == 0) - error = fdc_hints_probe(dev); - if (error == 0) - fdc_start_worker(dev); - else - fdc_release_resources(fdc); - return (error); -} - -static device_method_t fdc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fdc_isa_probe), - DEVMETHOD(device_attach, fdc_isa_attach), - DEVMETHOD(device_detach, fdc_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, fdc_print_child), - DEVMETHOD(bus_read_ivar, fdc_read_ivar), - DEVMETHOD(bus_write_ivar, fdc_write_ivar), - /* Our children never use any other bus interface methods. */ - - { 0, 0 } -}; - -static driver_t fdc_driver = { - "fdc", - fdc_methods, - sizeof(struct fdc_data) -}; - -DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0); Index: sys/dev/fdc/fdc_pccard.c =================================================================== --- sys/dev/fdc/fdc_pccard.c +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2004-2005 M. Warner Losh. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "pccarddevs.h" - -static int fdc_pccard_probe(device_t); -static int fdc_pccard_attach(device_t); - -static const struct pccard_product fdc_pccard_products[] = { - PCMCIA_CARD(YEDATA, EXTERNAL_FDD), -}; - -static int -fdc_pccard_alloc_resources(device_t dev, struct fdc_data *fdc) -{ - struct resource *res; - int rid, i; - - rid = 0; - res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (res == NULL) { - device_printf(dev, "cannot alloc I/O port range\n"); - return (ENXIO); - } - for (i = 0; i < FDC_MAXREG; i++) { - fdc->resio[i] = res; - fdc->ridio[i] = rid; - fdc->ioff[i] = i; - fdc->ioh[i] = rman_get_bushandle(res); - } - fdc->iot = rman_get_bustag(res); - - fdc->rid_irq = 0; - fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq, - RF_ACTIVE | RF_SHAREABLE); - if (fdc->res_irq == NULL) { - device_printf(dev, "cannot reserve interrupt line\n"); - return (ENXIO); - } - return (0); -} - -static int -fdc_pccard_probe(device_t dev) -{ - if (pccard_product_lookup(dev, fdc_pccard_products, - sizeof(fdc_pccard_products[0]), NULL) != NULL) { - device_set_desc(dev, "PC Card Floppy"); - return (0); - } - return (ENXIO); -} - -static int -fdc_pccard_attach(device_t dev) -{ - int error; - struct fdc_data *fdc; - device_t child; - - fdc = device_get_softc(dev); - fdc->flags = FDC_NODMA | FDC_NOFAST; - fdc->fdct = FDC_NE765; - error = fdc_pccard_alloc_resources(dev, fdc); - if (error == 0) - error = fdc_attach(dev); - if (error == 0) { - child = fdc_add_child(dev, "fd", -1); - device_set_flags(child, 0x24); - error = bus_generic_attach(dev); - } - if (error == 0) - fdc_start_worker(dev); - else - fdc_release_resources(fdc); - return (error); -} - -static device_method_t fdc_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fdc_pccard_probe), - DEVMETHOD(device_attach, fdc_pccard_attach), - DEVMETHOD(device_detach, fdc_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, fdc_print_child), - DEVMETHOD(bus_read_ivar, fdc_read_ivar), - DEVMETHOD(bus_write_ivar, fdc_write_ivar), - /* Our children never use any other bus interface methods. */ - - { 0, 0 } -}; - -static driver_t fdc_pccard_driver = { - "fdc", - fdc_pccard_methods, - sizeof(struct fdc_data) -}; - -DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0); -PCCARD_PNP_INFO(fdc_pccard_products); Index: sys/dev/fdc/fdcvar.h =================================================================== --- sys/dev/fdc/fdcvar.h +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2004-2005 M. Warner Losh. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* XXX should audit this file to see if additional copyrights needed */ - -enum fdc_type { - FDC_NE765, FDC_ENHANCED, FDC_UNKNOWN = -1 -}; - -/* - * Per controller structure (softc). - */ -struct fdc_data { - int fdcu; /* our unit number */ - int dmachan; - int flags; -#define FDC_HASDMA 0x01 -#define FDC_STAT_VALID 0x08 -#define FDC_HAS_FIFO 0x10 -#define FDC_NEEDS_RESET 0x20 -#define FDC_NODMA 0x40 /* Don't do DMA */ -#define FDC_NOFAST 0x80 /* Don't register isr as a fast one */ -#define FDC_KTHREAD_EXIT 0x1000 /* request worker thread to stop */ -#define FDC_KTHREAD_ALIVE 0x2000 /* worker thread is alive */ - struct fd_data *fd; /* The active drive */ - int retry; - int fdout; /* mirror of the w/o digital output reg */ - u_int status[7]; /* copy of the registers */ - enum fdc_type fdct; /* chip version of FDC */ - int fdc_errs; /* number of logged errors */ - struct bio_queue_head head; - struct bio *bp; /* active buffer */ - struct resource *res_irq, *res_drq; - int rid_irq, rid_drq; -#define FDC_MAXREG 8 - int ridio[FDC_MAXREG]; - struct resource *resio[FDC_MAXREG]; - bus_space_tag_t iot; - bus_space_handle_t ioh[FDC_MAXREG]; - int ioff[FDC_MAXREG]; - void *fdc_intr; - device_t fdc_dev; - struct mtx fdc_mtx; - struct proc *fdc_thread; -}; - -extern devclass_t fdc_devclass; - -enum fdc_device_ivars { - FDC_IVAR_FDUNIT, - FDC_IVAR_FDTYPE, -}; - -__BUS_ACCESSOR(fdc, fdunit, FDC, FDUNIT, int); -__BUS_ACCESSOR(fdc, fdtype, FDC, FDTYPE, int); - -void fdc_release_resources(struct fdc_data *); -int fdc_attach(device_t); -void fdc_start_worker(device_t); -int fdc_hints_probe(device_t); -int fdc_detach(device_t dev); -device_t fdc_add_child(device_t, const char *, int); -int fdc_initial_reset(device_t, struct fdc_data *); -int fdc_print_child(device_t, device_t); -int fdc_read_ivar(device_t, device_t, int, uintptr_t *); -int fdc_write_ivar(device_t, device_t, int, uintptr_t); -int fdc_isa_alloc_resources(device_t, struct fdc_data *); Index: sys/i386/conf/GENERIC =================================================================== --- sys/i386/conf/GENERIC +++ sys/i386/conf/GENERIC @@ -109,9 +109,6 @@ options PCI_HP # PCI-Express native HotPlug options PCI_IOV # PCI SR-IOV support -# Floppy drives -device fdc - # ATA controllers device ahci # AHCI-compatible SATA controllers device ata # Legacy ATA/SATA controllers Index: sys/i386/conf/GENERIC.hints =================================================================== --- sys/i386/conf/GENERIC.hints +++ sys/i386/conf/GENERIC.hints @@ -1,12 +1,4 @@ # $FreeBSD$ -hint.fdc.0.at="isa" -hint.fdc.0.port="0x3F0" -hint.fdc.0.irq="6" -hint.fdc.0.drq="2" -hint.fd.0.at="fdc0" -hint.fd.0.drive="0" -hint.fd.1.at="fdc0" -hint.fd.1.drive="1" hint.ata.0.at="isa" hint.ata.0.port="0x1F0" hint.ata.0.irq="14" Index: sys/isa/isahint.c =================================================================== --- sys/isa/isahint.c +++ sys/isa/isahint.c @@ -130,20 +130,6 @@ */ matches = 0; if (resource_long_value(name, unit, "port", &value) == 0) { - /* - * Floppy drive controllers are notorious for - * having a wide variety of resources not all - * of which include the first port that is - * specified by the hint (typically 0x3f0) - * (see the comment above - * fdc_isa_alloc_resources() in fdc_isa.c). - * However, they do all seem to include port + - * 2 (e.g. 0x3f2) so for a floppy device, look - * for 'value + 2' in the port resources - * instead of the hint value. - */ - if (strcmp(name, "fdc") == 0) - value += 2; if (isa_match_resource_hint(child, SYS_RES_IOPORT, value)) matches++; Index: sys/modules/Makefile =================================================================== --- sys/modules/Makefile +++ sys/modules/Makefile @@ -126,7 +126,6 @@ ${_ex} \ ${_exca} \ ext2fs \ - fdc \ fdescfs \ ${_fe} \ ${_ffec} \ Index: sys/modules/fdc/Makefile =================================================================== --- sys/modules/fdc/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -KMOD= fdc - -.PATH: ${SRCTOP}/sys/dev/fdc -SRCS= fdc.c fdc_isa.c fdc_pccard.c -.if ${MACHINE} == "i386" || ${MACHINE} == "amd64" -SRCS+= opt_acpi.h acpi_if.h fdc_acpi.c -.endif - -SRCS+= opt_fdc.h bus_if.h card_if.h device_if.h \ - isa_if.h pccarddevs.h - -.include Index: sys/powerpc/conf/NOTES =================================================================== --- sys/powerpc/conf/NOTES +++ sys/powerpc/conf/NOTES @@ -79,7 +79,6 @@ nodevice ccr nodevice cxgbe # XXX: builds on powerpc64 only. nodevice cxgbev -nodevice fdc nodevice ppc nodevice splash # when splash works enable *_saver Index: sys/sparc64/conf/GENERIC =================================================================== --- sys/sparc64/conf/GENERIC +++ sys/sparc64/conf/GENERIC @@ -100,9 +100,6 @@ device central device fhc -# Floppy drives -#device fdc - # ATA controllers device ahci # AHCI-compatible SATA controllers device ata # Legacy ATA/SATA controllers Index: sys/sparc64/conf/NOTES =================================================================== --- sys/sparc64/conf/NOTES +++ sys/sparc64/conf/NOTES @@ -93,7 +93,6 @@ nodevice snake_saver nodevice star_saver nodevice bktr -nodevice fdc nodevice ppc nodevice snd_ad1816 nodevice snd_als4000 @@ -128,7 +127,6 @@ ##################################################################### # Options we don't want to deal with -nooption FDC_DEBUG nooption COMPAT_FREEBSD4 nooption SC_RENDER_DEBUG nooption SC_DEBUG_LEVEL Index: sys/sparc64/isa/isa_dma.c =================================================================== --- sys/sparc64/isa/isa_dma.c +++ sys/sparc64/isa/isa_dma.c @@ -38,7 +38,7 @@ #include /* - * Glue code to load sound(4). Though fdc(4), ppc(4) don't work on + * Glue code to load sound(4). Though ppc(4) don't work on * sparc64 yet, they may need this glue code too. */ Index: targets/pseudo/userland/Makefile.depend =================================================================== --- targets/pseudo/userland/Makefile.depend +++ targets/pseudo/userland/Makefile.depend @@ -567,10 +567,6 @@ usr.sbin/etcupdate \ usr.sbin/extattr \ usr.sbin/extattrctl \ - usr.sbin/fdcontrol \ - usr.sbin/fdformat \ - usr.sbin/fdread \ - usr.sbin/fdwrite \ usr.sbin/fifolog/fifolog_create \ usr.sbin/fifolog/fifolog_reader \ usr.sbin/fifolog/fifolog_writer \ Index: tools/build/mk/OptionalObsoleteFiles.inc =================================================================== --- tools/build/mk/OptionalObsoleteFiles.inc +++ tools/build/mk/OptionalObsoleteFiles.inc @@ -2304,17 +2304,6 @@ OLD_FILES+=usr/share/man/man8/fingerd.8.gz .endif -.if ${MK_FLOPPY} == no -OLD_FILES+=usr/sbin/fdcontrol -OLD_FILES+=usr/sbin/fdformat -OLD_FILES+=usr/sbin/fdread -OLD_FILES+=usr/sbin/fdwrite -OLD_FILES+=usr/share/man/man1/fdformat.1.gz -OLD_FILES+=usr/share/man/man1/fdread.1.gz -OLD_FILES+=usr/share/man/man1/fdwrite.1.gz -OLD_FILES+=usr/share/man/man8/fdcontrol.8.gz -.endif - .if ${MK_FORTH} == no OLD_FILES+=usr/share/man/man5/loader.conf.5.gz OLD_FILES+=usr/share/man/man8/beastie.4th.8.gz Index: tools/kerneldoc/subsys/Doxyfile-dev_fdc =================================================================== --- tools/kerneldoc/subsys/Doxyfile-dev_fdc +++ /dev/null @@ -1,21 +0,0 @@ -# Doxyfile 1.5.2 - -# $FreeBSD$ - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = "FreeBSD kernel FDC device code" -OUTPUT_DIRECTORY = $(DOXYGEN_DEST_PATH)/dev_fdc/ -EXTRACT_ALL = YES # for undocumented src, no warnings enabled -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = $(DOXYGEN_SRC_PATH)/dev/fdc/ \ - $(NOTREVIEWED) - -GENERATE_TAGFILE = dev_fdc/dev_fdc.tag - -@INCLUDE_PATH = $(DOXYGEN_INCLUDE_PATH) -@INCLUDE = common-Doxyfile - Index: tools/tools/nanobsd/pcengines/ALIX_DSK =================================================================== --- tools/tools/nanobsd/pcengines/ALIX_DSK +++ tools/tools/nanobsd/pcengines/ALIX_DSK @@ -40,7 +40,6 @@ device cpufreq device acpi device pci -device fdc device ata options ATA_STATIC_ID device scbus Index: tools/tools/tinybsd/conf/bridge/TINYBSD =================================================================== --- tools/tools/tinybsd/conf/bridge/TINYBSD +++ tools/tools/tinybsd/conf/bridge/TINYBSD @@ -36,9 +36,6 @@ device eisa device pci -# Floppy drives -#device fdc - # ATA and ATAPI devices device ata device atadisk # ATA disk drives Index: tools/tools/tinybsd/conf/default/TINYBSD =================================================================== --- tools/tools/tinybsd/conf/default/TINYBSD +++ tools/tools/tinybsd/conf/default/TINYBSD @@ -42,9 +42,6 @@ device eisa device pci -# Floppy drives -#device fdc - # ATA and ATAPI devices device ata device atadisk # ATA disk drives Index: tools/tools/tinybsd/conf/firewall/TINYBSD =================================================================== --- tools/tools/tinybsd/conf/firewall/TINYBSD +++ tools/tools/tinybsd/conf/firewall/TINYBSD @@ -35,9 +35,6 @@ device eisa device pci -# Floppy drives -#device fdc - # ATA and ATAPI devices device ata device atadisk # ATA disk drives Index: tools/tools/tinybsd/conf/vpn/TINYBSD =================================================================== --- tools/tools/tinybsd/conf/vpn/TINYBSD +++ tools/tools/tinybsd/conf/vpn/TINYBSD @@ -35,9 +35,6 @@ device eisa device pci -# Floppy drives -#device fdc - # ATA and ATAPI devices device ata device atadisk # ATA disk drives Index: tools/tools/tinybsd/conf/wireless/TINYBSD =================================================================== --- tools/tools/tinybsd/conf/wireless/TINYBSD +++ tools/tools/tinybsd/conf/wireless/TINYBSD @@ -35,9 +35,6 @@ device eisa device pci -# Floppy drives -#device fdc - # ATA and ATAPI devices device ata device atadisk # ATA disk drives Index: usr.sbin/Makefile =================================================================== --- usr.sbin/Makefile +++ usr.sbin/Makefile @@ -124,10 +124,6 @@ SUBDIR.${MK_CXGBETOOL}+= cxgbetool SUBDIR.${MK_DIALOG}+= bsdconfig SUBDIR.${MK_EFI}+= efivar efidp -SUBDIR.${MK_FLOPPY}+= fdcontrol -SUBDIR.${MK_FLOPPY}+= fdformat -SUBDIR.${MK_FLOPPY}+= fdread -SUBDIR.${MK_FLOPPY}+= fdwrite SUBDIR.${MK_FMTREE}+= fmtree SUBDIR.${MK_FREEBSD_UPDATE}+= freebsd-update SUBDIR.${MK_GSSAPI}+= gssd Index: usr.sbin/fdcontrol/Makefile =================================================================== --- usr.sbin/fdcontrol/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR:H}/fdread - -PROG= fdcontrol -SRCS= fdcontrol.c fdutil.c -CFLAGS+= -I${.CURDIR:H}/fdread -MAN= fdcontrol.8 - -.include Index: usr.sbin/fdcontrol/Makefile.depend =================================================================== --- usr.sbin/fdcontrol/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.sbin/fdcontrol/fdcontrol.8 =================================================================== --- usr.sbin/fdcontrol/fdcontrol.8 +++ /dev/null @@ -1,310 +0,0 @@ -.\" Copyright (C) 1994, 2001 by Joerg Wunsch, Dresden -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -.\" OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -.\" USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -.\" DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd April 7, 2017 -.Dt FDCONTROL 8 -.Os -.Sh NAME -.Nm fdcontrol -.Nd display and modify floppy disk parameters -.Sh SYNOPSIS -.Nm -.Op Fl F -.Op Fl d Ar dbg -.Op Fl f Ar fmt -.Op Fl s Ar fmtstr -.Op Fl v -.Ar device -.Sh DESCRIPTION -The -.Nm -utility allows the modification of the run-time behavior of the -.Xr fdc 4 -driver for the device specified by -.Ar device . -.Pp -Commands are implemented to query the current device density settings -as well as the underlying device hardware as registered with the -driver, to manipulate debugging levels, and to adjust the device -density settings. -All the operations that manipulate the kernel -settings are restricted to the superuser (by the device driver), while -all inquiry requests only require read access to -.Ar device . -.Pp -The -.Ar device -argument should always be given as a full path name, e.g.\& -.Pa /dev/fd0 . -.Ss Inquiry Commands -Running the -.Nm -utility without any of the optional flags will report the drive type -that is registered with the device driver. -In the shortest form, a single string describing the drive type will -be returned. -Possible values are: -.Dq Li 360K , -.Dq Li 1.2M , -.Dq Li 720K , -.Dq Li 1.44M , -.Dq Li 2.88M , -or -.Dq Li unknown . -This information is primarily intended to be easily parsable by -scripts. -.Pp -In order to add some descriptive text that makes the output better -human readable, the flag -.Fl v -can be added. -.Pp -Specifying flag -.Fl F -will report the device's density settings in a form that is suitable -as input to the -.Fl s Ar fmtstr -option (see below). -Again, together with -.Fl v , -some more text will be returned, including the total capacity of the -density settings in kilobytes. -.Ss Debug Control -The -.Xr fdc 4 -control utilities support two different options how to specify device -density settings. -The first form uses -.Fl f Ar fmt -to specify the format of the medium in kilobytes. -Depending on the -underlying drive type, the value is compared against a table of known -commonly used device density settings for that drive, and if a match -is found, those settings will be used. -Currently, the following -values for the respective drive types are acceptable: -.Bl -item -.It -2.88M and 1.44M drives: -.Bd -ragged -offset indent -compact -.TS -lB lB lB lB lB lB lB -r l l l l l l. -KB sectrac secsize ncyls speed heads flags -1721 21 2 (512) 82 500 2 MFM -1476 18 2 (512) 82 500 2 MFM -1440 18 2 (512) 80 500 2 MFM -1200 15 2 (512) 80 500 2 MFM -820 10 2 (512) 82 250 2 MFM -800 10 2 (512) 80 250 2 MFM -720 9 2 (512) 80 250 2 MFM -.TE -.Ed -.It -1.2M drives: -.Bd -ragged -offset indent -compact -.TS -lB lB lB lB lB lB lB -r l l l l l l. -KB sectrac secsize ncyls speed heads flags -1200 15 2 (512) 80 500 2 MFM -1232 8 3 (1024) 77 500 2 MFM -1476 18 2 (512) 82 500 2 MFM -1440 18 2 (512) 80 500 2 MFM -1200 15 2 (512) 80 500 2 MFM -820 10 2 (512) 82 300 2 MFM -800 10 2 (512) 80 300 2 MFM -720 9 2 (512) 80 300 2 MFM -360 9 2 (512) 40 300 2 MFM,2STEP -640 8 2 (512) 80 300 2 MFM -.TE -.Ed -.It -720K drives: -.Bd -ragged -offset indent -compact -.TS -lB lB lB lB lB lB lB -r l l l l l l. -KB sectrac secsize ncyls speed heads flags -720 9 2 (512) 80 250 2 MFM -.TE -.Ed -.It -360K drives: -.Bd -ragged -offset indent -compact -.TS -lB lB lB lB lB lB lB -r l l l l l l. -KB sectrac secsize ncyls speed heads flags -360 9 2 (512) 40 250 2 MFM -.TE -.Ed -.El -.Pp -The second form to specify a device density uses -.Fl s Ar fmtstr -to explicitly specify each parameter in detail. -The argument -.Ar fmtstr -is a comma-separated list of values of the form: -.Pp -.Sm off -.Ar sectrac , secsize , datalen , gap , ncyls , speed , -.Ar heads , f_gap , f_inter , offs2 , flags -.Sm on -.Pp -The meaning of the parameters is: -.Bl -tag -width ".Ar secsize" -.It Ar sectrac -The number of sectors per track. -.It Ar secsize -The sector size code, 0 = 128 bytes (or less), 1 = 256 bytes, 2 = 512 -bytes, 3 = 1024 bytes. -.It Ar datalen -The actual sector size if the size code is 0, or the (ignored) value -0xFF for larger size codes. -.It Ar gap -The length of the gap 3 parameter for read/write operations. -.It Ar ncyls -The number of cylinders. -.It Ar speed -The transfer speed in kilobytes per second. -Can be 250, 300, 500, or -1000, but each drive type only supports a subset of these values. -.It Ar heads -The number of heads. -.It Ar f_gap -The length of the gap 3 when formatting media. -.It Ar f_inter -The sector interleave to be applied when formatting. -0 means no -interleave, 1 means 1:1 etc. -.It Ar offs2 -The offset of the sector numbers on side 2 (i.e., head number 1). -Normally, sector numbering on both sides starts with 1. -.It Ar flags -A list from one of the following flag values: -.Pp -.Bl -tag -width ".Cm +perpend" -compact -.It Cm +mfm -Use MFM encoding. -.It Cm -mfm -Use FM (single-density) encoding. -.It Cm +2step -Use 2 steps per each cylinder (for accessing 40-cylinder media in -80-cylinder drives). -.It Cm -2step -Do not use 2 steps per cylinder, i.e., access each physical cylinder -of the drive. -.It Cm +perpend -Use perpendicular recording (for 2.88 MB media, currently not -supported). -.It Cm -perpend -Use longitudinal recording. -.El -.El -.Pp -For any missing parameter, the current value will be used, so only -actual changes need to be specified. -Thus to turn off a flag bit -(like -.Cm +mfm -which is the default for all drive types), the form with a leading -minus sign must explicitly be used. -.Sh EXAMPLES -A simple inquiry about the drive type: -.Bd -literal -offset indent -$ fdcontrol /dev/fd0 -1.44M -.Ed -.Pp -Same as above, but with verbose output. -Note that the result is about -the -.Em "drive type" , -as opposed to a -.Em "device density" , -so it is independent from the actual subdevice being used for -.Ar device . -.Bd -literal -offset indent -$ fdcontrol -v /dev/fd0 -/dev/fd0: 1.44M drive (3.5" high-density) -.Ed -.Pp -Inquiry about the density settings: -.Bd -literal -offset indent -$ fdcontrol -F /dev/fd0 -18,512,0xff,0x1b,80,500,2,0x6c,1,0,+mfm -.Ed -.Pp -The verbose flag makes this human readable: -.Bd -literal -offset indent -/dev/fd0: 1440 KB media type - Format: 18,512,0xff,0x1b,80,500,2,0x6c,1,0,+mfm - Sector size: 512 - Sectors/track: 18 - Heads/cylinder: 2 - Cylinders/disk: 80 - Transfer rate: 500 kbps - Sector gap: 27 - Format gap: 108 - Interleave: 1 - Side offset: 0 - Flags -.Ed -.Pp -As indicated, trailing commas in the parameter list may be omitted. -.Pp -In order to access archaic 160 KB single-density (FM encoded) 5.25 -media in a modern 1.2M drive, something like the following definition -would be needed. -(Note that not all controller hardware is actually -capable of handling FM encoding at all.) -.Bd -literal -# fdcontrol -s 16,128,0x80,0x2,40,300,,0x10,,,-mfm,+2step /dev/fd1.1 -.Ed -.Pp -It is still possible to hook up 8" drives to most modern floppy -controllers, given the right cable magic. -(On PC hardware, tell the BIOS that it is a 5.25" drive.) -The classical 128/26/2/77 format can be read with this entry -.Bd -literal -offset indent -fdcontrol -s 26,128,0x80,0x2,77,500,2,0x10,,,-mfm /dev/fd0 -.Ed -.Sh SEE ALSO -.Xr fdc 4 -.Sh HISTORY -The -.Nm -utility appeared in -.Fx 2.0 , -and was vastly overhauled in -.Fx 5.0 . -.Sh AUTHORS -The program and this man page was contributed by -.An J\(:org Wunsch , -Dresden. Index: usr.sbin/fdcontrol/fdcontrol.c =================================================================== --- usr.sbin/fdcontrol/fdcontrol.c +++ /dev/null @@ -1,211 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 1994, 2001 by Joerg Wunsch, Dresden - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "fdutil.h" - - -static int format, verbose, show = 1, showfmt; -static char *fmtstring; - -static void showdev(enum fd_drivetype, const char *); -static void usage(void); - -static void -usage(void) -{ - errx(EX_USAGE, - "usage: fdcontrol [-F] [-d dbg] [-f fmt] [-s fmtstr] [-v] device"); -} - -void -showdev(enum fd_drivetype type, const char *fname) -{ - const char *name, *descr; - - getname(type, &name, &descr); - if (verbose) - printf("%s: %s drive (%s)\n", fname, name, descr); - else - printf("%s\n", name); -} - -int -main(int argc, char **argv) -{ - enum fd_drivetype type; - struct fd_type ft, newft, *fdtp; - const char *name, *descr; - int fd, i, autofmt; - - autofmt = 0; - while((i = getopt(argc, argv, "aFf:s:v")) != -1) - switch(i) { - - case 'a': - autofmt = 1; - case 'F': - showfmt = 1; - show = 0; - break; - - case 'f': - if (!strcmp(optarg, "auto")) { - format = -1; - } else if (getnum(optarg, &format)) { - fprintf(stderr, - "Bad argument %s to -f option; must be numeric\n", - optarg); - usage(); - } - show = 0; - break; - - case 's': - fmtstring = optarg; - show = 0; - break; - - case 'v': - verbose++; - break; - - default: - usage(); - } - - argc -= optind; - argv += optind; - - if(argc != 1) - usage(); - - if((fd = open(argv[0], O_RDONLY | O_NONBLOCK)) < 0) - err(EX_UNAVAILABLE, "open(%s)", argv[0]); - - if (ioctl(fd, FD_GDTYPE, &type) == -1) - err(EX_OSERR, "ioctl(FD_GDTYPE)"); - if (ioctl(fd, FD_GTYPE, &ft) == -1) - err(EX_OSERR, "ioctl(FD_GTYPE)"); - - if (show) { - showdev(type, argv[0]); - return (0); - } - - if (autofmt) { - memset(&newft, 0, sizeof newft); - ft = newft; - } - - if (format) { - getname(type, &name, &descr); - fdtp = get_fmt(format, type); - if (fdtp == 0) - errx(EX_USAGE, - "unknown format %d KB for drive type %s", - format, name); - ft = *fdtp; - } - - if (fmtstring) { - parse_fmt(fmtstring, type, ft, &newft); - ft = newft; - } - - if (showfmt) { - if (verbose) { - const char *s; - - printf("%s: %d KB media type\n", argv[0], - (128 << ft.secsize) * ft.size / 1024); - printf("\tFormat:\t\t"); - print_fmt(ft); - if (ft.datalen != 0xff && - ft.datalen != (128 << ft.secsize)) - printf("\tData length:\t%d\n", ft.datalen); - printf("\tSector size:\t%d\n", 128 << ft.secsize); - printf("\tSectors/track:\t%d\n", ft.sectrac); - printf("\tHeads/cylinder:\t%d\n", ft.heads); - printf("\tCylinders/disk:\t%d\n", ft.tracks); - switch (ft.trans) { - case 0: printf("\tTransfer rate:\t500 kbps\n"); break; - case 1: printf("\tTransfer rate:\t300 kbps\n"); break; - case 2: printf("\tTransfer rate:\t250 kbps\n"); break; - case 3: printf("\tTransfer rate:\t1 Mbps\n"); break; - } - printf("\tSector gap:\t%d\n", ft.gap); - printf("\tFormat gap:\t%d\n", ft.f_gap); - printf("\tInterleave:\t%d\n", ft.f_inter); - printf("\tSide offset:\t%d\n", ft.offset_side2); - printf("\tFlags\t\t<"); - s = ""; - if (ft.flags & FL_MFM) { - printf("%sMFM", s); - s = ","; - } - if (ft.flags & FL_2STEP) { - printf("%s2STEP", s); - s = ","; - } - if (ft.flags & FL_PERPND) { - printf("%sPERPENDICULAR", s); - s = ","; - } - if (ft.flags & FL_AUTO) { - printf("%sAUTO", s); - s = ","; - } - printf(">\n"); - } else { - print_fmt(ft); - } - return (0); - } - - if (format || fmtstring) { - if (ioctl(fd, FD_STYPE, &ft) == -1) - err(EX_OSERR, "ioctl(FD_STYPE)"); - return (0); - } - - return 0; -} Index: usr.sbin/fdformat/Makefile =================================================================== --- usr.sbin/fdformat/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR:H}/fdread - -PROG= fdformat -SRCS= fdformat.c fdutil.c - -CFLAGS+= -I${.CURDIR:H}/fdread - -.include Index: usr.sbin/fdformat/Makefile.depend =================================================================== --- usr.sbin/fdformat/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.sbin/fdformat/fdformat.1 =================================================================== --- usr.sbin/fdformat/fdformat.1 +++ /dev/null @@ -1,180 +0,0 @@ -.\" Copyright (C) 1993, 1994, 1995, 2001 by Joerg Wunsch, Dresden -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS -.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, -.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd December 25, 2001 -.Dt FDFORMAT 1 -.Os -.Sh NAME -.Nm fdformat -.Nd format floppy disks -.Sh SYNOPSIS -.Nm -.Op Fl F Ar fill -.Op Fl f Ar fmt -.Op Fl s Ar fmtstr -.Op Fl nqvy -.Ar device -.Sh DESCRIPTION -The -.Nm -utility formats a floppy disk at -.Ar device , -where -.Ar device -may either be given as a full path -name of a device node for a floppy disk drive -(e.g.\& -.Pa /dev/fd0 ) , -or using an abbreviated name that will be looked up -under -.Pa /dev -(e.g.\& -.Dq Li fd0 ) . -.Pp -The options are as follows: -.Bl -tag -width ".Fl s Ar fmtstr" -.It Fl F Ar fill -Use -.Ar fill -as the fill byte for newly formatted sectors. -The -.Ar fill -argument -must be a number in the range 0 through 255 using common C -language notation. -The default value is -.Dq Li 0xf6 . -.It Fl f Ar fmt -Specify the density settings for a -.Ar fmt -kilobyte format, as described in -.Xr fdcontrol 8 . -.It Fl s Ar fmtstr -Specify the density settings using explicit parameters, as -described in -.Xr fdcontrol 8 . -.It Fl n -Do not verify floppy after formatting. -.It Fl q -Suppress any normal output from the command, and do not ask the -user for a confirmation whether to format the floppy disk at -.Ar device . -.It Fl v -Do not format, verify only. -.It Fl y -Do not ask for confirmation whether to format the floppy disk but -still report formatting status. -.El -.Pp -For non-autoselecting subdevices, neither -.Fl f Ar fmt -nor -.Fl s Ar fmtstr -may be specified, since the preconfigured media density settings -from the kernel driver will always be used. -However, if -.Ar device -is a device with automatic media density selection (see -.Xr fdc 4 ) , -both methods can be used to override the density settings for the -newly formatted medium (without permanently changing the density -settings of -.Ar device ) . -.Pp -If the -.Fl q -flag has not been specified, the user is asked for a confirmation -of the intended formatting process. -In order to continue, an answer -of -.Ql y -must be given. -.Pp -Note that -.Nm -does only perform low-level formatting. -In order to create -a file system on the medium, see the commands -.Xr newfs 8 -for a -.Tn UFS -file system, or -.Xr newfs_msdos 8 -for an -.Tn MS-DOS -(FAT) -file system. -.Sh EXIT STATUS -An exit status of 0 is returned upon successful operation. -Exit status -1 is returned on any errors during floppy formatting, and an exit status -of 2 reflects invalid arguments given to the program (along with an -appropriate information written to diagnostic output). -.Sh DIAGNOSTICS -Unless -.Fl q -has been specified, a single letter is printed to standard output -to inform the user about the progress of work. -First, an -.Ql F -is printed when the track is being formatted, then a -.Ql V -while it is being verified, and if an error has been detected, it -will finally change to -.Ql E . -Detailed status information (cylinder, head and sector number, and the -exact cause of the error) will be printed for up to 10 errors after the -entire formatting process has completed. -.Sh SEE ALSO -.Xr fdc 4 , -.Xr fdcontrol 8 , -.Xr newfs 8 , -.Xr newfs_msdos 8 -.Sh HISTORY -The -.Nm -utility -has been developed for -.Bx 386 0.1 -and upgraded to the new -.Xr fdc 4 -floppy disk driver. -It later became part of the -.Fx 1.1 -system. -Starting with -.Fx 5.0 , -it uses the unified density specifications as described in -.Xr fdcontrol 8 . -.Sh AUTHORS -.An -nosplit -The program has been contributed by -.An J\(:org Wunsch , -Dresden, with changes by -.An Serge Vakulenko -and -.An Andrey A. Chernov , -Moscow. Index: usr.sbin/fdformat/fdformat.c =================================================================== --- usr.sbin/fdformat/fdformat.c +++ /dev/null @@ -1,362 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 1992-1994,2001 by Joerg Wunsch, Dresden - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fdutil.h" - -static void -format_track(int fd, int cyl, int secs, int head, int rate, - int gaplen, int secsize, int fill, int interleave, - int offset) -{ - struct fd_formb f; - int i, j, il[FD_MAX_NSEC + 1]; - - memset(il, 0, sizeof il); - for(j = 0, i = 1 + offset; i <= secs + offset; i++) { - while(il[(j % secs) + 1]) - j++; - il[(j % secs) + 1] = i; - j += interleave; - } - - f.format_version = FD_FORMAT_VERSION; - f.head = head; - f.cyl = cyl; - f.transfer_rate = rate; - - f.fd_formb_secshift = secsize; - f.fd_formb_nsecs = secs; - f.fd_formb_gaplen = gaplen; - f.fd_formb_fillbyte = fill; - for(i = 0; i < secs; i++) { - f.fd_formb_cylno(i) = cyl; - f.fd_formb_headno(i) = head; - f.fd_formb_secno(i) = il[i+1]; - f.fd_formb_secsize(i) = secsize; - } - (void)ioctl(fd, FD_FORM, (caddr_t)&f); -} - -static int -verify_track(int fd, int track, int tracksize) -{ - static char *buf; - static int bufsz; - int fdopts = -1, ofdopts, rv = 0; - - if (ioctl(fd, FD_GOPTS, &fdopts) < 0) - warn("warning: ioctl(FD_GOPTS)"); - else { - ofdopts = fdopts; - fdopts |= FDOPT_NORETRY; - (void)ioctl(fd, FD_SOPTS, &fdopts); - } - - if (bufsz < tracksize) - buf = realloc(buf, bufsz = tracksize); - if (buf == NULL) - errx(EX_UNAVAILABLE, "out of memory"); - if (lseek (fd, (long) track * tracksize, 0) < 0) - rv = -1; - /* try twice reading it, without using the normal retrier */ - else if (read (fd, buf, tracksize) != tracksize - && read (fd, buf, tracksize) != tracksize) - rv = -1; - if (fdopts != -1) - (void)ioctl(fd, FD_SOPTS, &ofdopts); - return (rv); -} - -static void -usage (void) -{ - errx(EX_USAGE, - "usage: fdformat [-F fill] [-f fmt] [-s fmtstr] [-nqvy] device"); -} - -static int -yes (void) -{ - char reply[256], *p; - - reply[sizeof(reply) - 1] = 0; - for (;;) { - fflush(stdout); - if (!fgets (reply, sizeof(reply) - 1, stdin)) - return (0); - for (p=reply; *p==' ' || *p=='\t'; ++p) - continue; - if (*p=='y' || *p=='Y') - return (1); - if (*p=='n' || *p=='N' || *p=='\n' || *p=='\r') - return (0); - printf("Answer `yes' or `no': "); - } -} - -int -main(int argc, char **argv) -{ - enum fd_drivetype type; - struct fd_type fdt, newft, *fdtp; - struct stat sb; -#define MAXPRINTERRS 10 - struct fdc_status fdcs[MAXPRINTERRS]; - int format, fill, quiet, verify, verify_only, confirm; - int fd, c, i, track, error, tracks_per_dot, bytes_per_track, errs; - int flags; - char *fmtstring, *device; - const char *name, *descr; - - format = quiet = verify_only = confirm = 0; - verify = 1; - fill = 0xf6; - fmtstring = 0; - - while((c = getopt(argc, argv, "F:f:nqs:vy")) != -1) - switch(c) { - case 'F': /* fill byte */ - if (getnum(optarg, &fill)) { - fprintf(stderr, - "Bad argument %s to -F option; must be numeric\n", - optarg); - usage(); - } - break; - - case 'f': /* format in kilobytes */ - if (getnum(optarg, &format)) { - fprintf(stderr, - "Bad argument %s to -f option; must be numeric\n", - optarg); - usage(); - } - break; - - case 'n': /* don't verify */ - verify = 0; - break; - - case 'q': /* quiet */ - quiet = 1; - break; - - case 's': /* format string with detailed options */ - fmtstring = optarg; - break; - - case 'v': /* verify only */ - verify = 1; - verify_only = 1; - break; - - case 'y': /* confirm */ - confirm = 1; - break; - - default: - usage(); - } - - if(optind != argc - 1) - usage(); - - if (stat(argv[optind], &sb) == -1 && errno == ENOENT) { - /* try prepending _PATH_DEV */ - device = malloc(strlen(argv[optind]) + sizeof(_PATH_DEV) + 1); - if (device == NULL) - errx(EX_UNAVAILABLE, "out of memory"); - strcpy(device, _PATH_DEV); - strcat(device, argv[optind]); - if (stat(device, &sb) == -1) { - free(device); - device = argv[optind]; /* let it fail below */ - } - } else { - device = argv[optind]; - } - - if ((fd = open(device, O_RDWR | O_NONBLOCK)) < 0) - err(EX_OSERR, "open(%s)", device); - - /* - * Device initialization. - * - * First, get the device type descriptor. This tells us about - * the media geometry data we need to format a medium. It also - * lets us know quickly whether the device name actually points - * to a floppy disk drive. - * - * Then, obtain any drive options. We're mainly interested to - * see whether we're currently working on a device with media - * density autoselection (FDOPT_AUTOSEL). Then, we add the - * device option to tell the kernel not to log media errors, - * since we can handle them ourselves. If the device does - * media density autoselection, we then need to set the device - * type appropriately, since by opening with O_NONBLOCK we - * told the driver to bypass media autoselection (otherwise we - * wouldn't stand a chance to format an unformatted or damaged - * medium). We do not attempt to set the media type on any - * other devices since this is a privileged operation. For the - * same reason, specifying -f and -s options is only possible - * for autoselecting devices. - * - * Finally, we are ready to turn off O_NONBLOCK, and start to - * actually format something. - */ - if(ioctl(fd, FD_GTYPE, &fdt) < 0) - errx(EX_OSERR, "not a floppy disk: %s", device); - if (ioctl(fd, FD_GDTYPE, &type) == -1) - err(EX_OSERR, "ioctl(FD_GDTYPE)"); - if (format) { - getname(type, &name, &descr); - fdtp = get_fmt(format, type); - if (fdtp == NULL) - errx(EX_USAGE, - "unknown format %d KB for drive type %s", - format, name); - fdt = *fdtp; - } - if (fmtstring) { - parse_fmt(fmtstring, type, fdt, &newft); - fdt = newft; - } - if (ioctl(fd, FD_STYPE, &fdt) < 0) - err(EX_OSERR, "ioctl(FD_STYPE)"); - if ((flags = fcntl(fd, F_GETFL, 0)) == -1) - err(EX_OSERR, "fcntl(F_GETFL)"); - flags &= ~O_NONBLOCK; - if (fcntl(fd, F_SETFL, flags) == -1) - err(EX_OSERR, "fcntl(F_SETFL)"); - - bytes_per_track = fdt.sectrac * (128 << fdt.secsize); - - /* XXX 20/40 = 0.5 */ - tracks_per_dot = (fdt.tracks * fdt.heads + 20) / 40; - - if (verify_only) { - if(!quiet) - printf("Verify %dK floppy `%s'.\n", - fdt.tracks * fdt.heads * bytes_per_track / 1024, - device); - } - else if(!quiet && !confirm) { - printf("Format %dK floppy `%s'? (y/n): ", - fdt.tracks * fdt.heads * bytes_per_track / 1024, - device); - if(!yes()) { - printf("Not confirmed.\n"); - return (EX_UNAVAILABLE); - } - } - - /* - * Formatting. - */ - if(!quiet) { - printf("Processing "); - for (i = 0; i < (fdt.tracks * fdt.heads) / tracks_per_dot; i++) - putchar('-'); - printf("\rProcessing "); - fflush(stdout); - } - - error = errs = 0; - - for (track = 0; track < fdt.tracks * fdt.heads; track++) { - if (!verify_only) { - format_track(fd, track / fdt.heads, fdt.sectrac, - track % fdt.heads, fdt.trans, fdt.f_gap, - fdt.secsize, fill, fdt.f_inter, - track % fdt.heads? fdt.offset_side2: 0); - if(!quiet && !((track + 1) % tracks_per_dot)) { - putchar('F'); - fflush(stdout); - } - } - if (verify) { - if (verify_track(fd, track, bytes_per_track) < 0) { - error = 1; - if (errs < MAXPRINTERRS && errno == EIO) { - if (ioctl(fd, FD_GSTAT, fdcs + errs) == - -1) - errx(EX_IOERR, - "floppy IO error, but no FDC status"); - errs++; - } - } - if(!quiet && !((track + 1) % tracks_per_dot)) { - if (!verify_only) - putchar('\b'); - if (error) { - putchar('E'); - error = 0; - } - else - putchar('V'); - fflush(stdout); - } - } - } - if(!quiet) - printf(" done.\n"); - - if (!quiet && errs) { - fflush(stdout); - fprintf(stderr, "Errors encountered:\nCyl Head Sect Error\n"); - for (i = 0; i < errs && i < MAXPRINTERRS; i++) { - fprintf(stderr, " %2d %2d %2d ", - fdcs[i].status[3], fdcs[i].status[4], - fdcs[i].status[5]); - printstatus(fdcs + i, 1); - putc('\n', stderr); - } - if (errs >= MAXPRINTERRS) - fprintf(stderr, "(Further errors not printed.)\n"); - } - - return errs != 0; -} Index: usr.sbin/fdread/Makefile =================================================================== --- usr.sbin/fdread/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $FreeBSD$ - -PROG= fdread -SRCS= fdread.c fdutil.c - -.include Index: usr.sbin/fdread/Makefile.depend =================================================================== --- usr.sbin/fdread/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.sbin/fdread/fdread.1 =================================================================== --- usr.sbin/fdread/fdread.1 +++ /dev/null @@ -1,233 +0,0 @@ -.\" -.\" Copyright (c) 2001 Joerg Wunsch -.\" -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.\" -.Dd May 14, 2001 -.Dt FDREAD 1 -.Os -.Sh NAME -.Nm fdread -.Nd read floppy disks -.Sh SYNOPSIS -.Nm -.Op Fl qr -.Op Fl d Ar device -.Op Fl f Ar fillbyte -.Op Fl o Ar file -.Nm -.Op Fl d Ar device -.Fl I Ar numsects -.Op Fl t Ar trackno -.Sh DESCRIPTION -The -.Nm -utility reads floppy disks. -Effective read blocking based on the track -size is performed, and floppy-specific error recovery of otherwise -bad blocks can be enabled. -.Pp -The -.Nm -utility -will always read an entire floppy medium, and write its contents to -the respective output file. -Unlike other tools like -.Xr dd 1 , -.Nm -automatically uses a read block size that is more efficient than -reading single blocks (usually one track of data at a time), but -falls back to reading single floppy sectors in case of an input/output -error occurred, in order to obtain as much valid data as possible. -While -.Nm -is working, kernel error reporting for floppy errors is turned off, so -the console and/or syslog are not flooded with kernel error messages. -.Pp -The -.Nm -utility accepts the following options: -.Bl -tag -width indent -.It Fl q -Turn on quiet mode. -By default, the medium parameters of the device -are being written to standard error output, progress will be indicated -by the approximate number of kilobytes read so far, and errors will be -printed out in detail, including the information about the location of -recovered data in the output. -In quiet mode, none of these messages -will be generated. -.It Fl r -Enable error recovery. -By default, -.Nm -stops after the first unrecovered read error, much like -.Xr dd 1 -does. -In recovery mode, however, one of two recovery actions will be -taken: -.Bl -bullet -.It -If the error was a CRC error in the data field, the -kernel is told to ignore the error, and data are transferred to the -output file anyway. -.Bf -emphasis -Note that this will cause the erroneous data -to be included in the output file! -.Ef -Still, this is the best recovery action that can be taken at all. -.It -All other errors are really fatal (usually, the FDC did not find the -sector ID fields), thus a dummy block with fill -bytes will be included in the output file. -.El -.Pp -Unless operating in quiet mode, the action taken and the location of -the error in the output file will be displayed. -.It Fl d Ar device -Specify the input floppy device, defaulting to -.Pa /dev/fd0 . -The parameter -.Ar device -must be a valid floppy disk device. -.It Fl f Ar fillbyte -Value of the fill byte used for dummy blocks in the output file in -recovery mode. -Defaults to -.Ql 0xf0 . -(Mnemonic: -.Dq foo . ) -The value can be specified using the usual C language notation of -the number base. -.It Fl o Ar file -Specify the output file to be -.Ar file . -By default, the data will be written to standard output. -.It Fl I Ar numsects -Read -.Ar numsects -sector ID fields, and write out their contents to standard output. -Each sector ID field contains recorded values for the cylinder number -.Pq Ql C , -the head number -.Pq Ql H , -the record number (sector number starting with 1) -.Pq Ql R , -and the -.Em sector shift value -(0 = 128 bytes, 1 = 256 bytes, 2 = 512 bytes, 3 = 1024 bytes) -.Pq Ql N . -The -.Fl I -option is mutually exclusive with all other options except -.Fl d Ar device -and -.Fl t Ar trackno . -.It Fl t Ar trackno -Specify the track number (cylinder number * number of heads + head -number) to read the sector ID fields from; only allowed together with -the -.Fl I Ar numsects -option. -.El -.Sh FILES -.Bl -tag -width /dev/fd0 -.It Pa /dev/fd0 -Default device to read from. -.El -.Sh EXIT STATUS -The -.Nm -utility sets the exit value according to -.Xr sysexits 3 . -In recovery mode, the exit value will be set to -.Dv EX_IOERR -if any error occurred during processing (even in quiet mode). -.Sh DIAGNOSTICS -Unless running in quiet mode, upon encountering an error, the status -of the floppy disc controller (FDC) will be printed out, both in -hexadecimal form, followed by a textual description that translates -those values into a human-readable form for the most common error -cases that can happen in a PC environment. -.Pp -The FDC error status includes the three FDC status registers -.Ql ST0 , -.Ql ST1 , -and -.Ql ST2 , -as well as the location of the error (physical cylinder, head, and sector -number, plus the -.Dq sector shift value , -respectively). -See the manual for the NE765 or compatible for details -about the status register contents. -.Pp -The FDC's status is then examined to determine whether the error is -deemed to be recoverable. -If error recovery was requested, the -location of the bad block in the output file is indicated by its -(hexadecimal) bounds. -Also, a summary line indicating the total number -of transfer errors will be printed before exiting. -.Sh SEE ALSO -.Xr dd 1 , -.Xr fdwrite 1 , -.Xr sysexits 3 , -.Xr fdc 4 , -.Xr fdcontrol 8 -.Sh HISTORY -The -.Nm -utility was written mainly to provide a means of recovering at least some of -the data on bad media, and to obviate the need to invoke -.Xr dd 1 -with too many hard to memorize options that might be useful to handle -a floppy. -.Pp -The command appeared in -.Fx 5.0 . -.Sh AUTHORS -Program and man page by -.An J\(:org Wunsch . -.Sh BUGS -Concurrent traffic on the second floppy drive located at the same FDC -will make error recovery attempts pointless, since the FDC status -obtained after a read error occurred cannot be guaranteed to actually -belong to the erroneous transfer. -Thus using option -.Fl r -is only reliable if -.Ar device -is the only active drive on that controller. -.Pp -No attempt beyond the floppy error retry mechanism of -.Xr fdc 4 -is made in order to see whether bad sectors could still be read -without errors by trying multiple times. -.Pp -Bits that are (no longer) available on the floppy medium cannot be -guessed by -.Nm . Index: usr.sbin/fdread/fdread.c =================================================================== --- usr.sbin/fdread/fdread.c +++ /dev/null @@ -1,336 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2001 Joerg Wunsch - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "fdutil.h" - -static int quiet, recover; -static unsigned char fillbyte = 0xf0; /* "foo" */ - -static int doread(int fd, FILE *of, const char *_devname); -static int doreadid(int fd, unsigned int numids, unsigned int trackno); -static void usage(void); - -static void -usage(void) -{ - - errx(EX_USAGE, - "usage: fdread [-qr] [-d device] [-f fillbyte]\n" - " fdread [-d device] -I numids [-t trackno]"); -} - - -int -main(int argc, char **argv) -{ - int c, errs = 0; - unsigned int numids = 0, trackno = 0; - const char *fname = 0, *_devname = "/dev/fd0"; - char *cp; - FILE *of = stdout; - int fd; - unsigned long ul; - - while ((c = getopt(argc, argv, "d:f:I:o:qrt:")) != -1) - switch (c) { - case 'd': - _devname = optarg; - break; - - case 'f': - ul = strtoul(optarg, &cp, 0); - if (*cp != '\0') { - fprintf(stderr, - "Bad argument %s to -f option; must be numeric\n", - optarg); - usage(); - } - if (ul > 0xff) - warnx( - "Warning: fillbyte %#lx too large, truncating\n", - ul); - fillbyte = ul & 0xff; - break; - - case 'I': - ul = strtoul(optarg, &cp, 0); - if (*cp != '\0') { - fprintf(stderr, - "Bad argument %s to -I option; must be numeric\n", - optarg); - usage(); - } - numids = ul; - break; - - case 'o': - fname = optarg; - break; - - case 'q': - quiet++; - break; - - case 'r': - recover++; - break; - - case 't': - ul = strtoul(optarg, &cp, 0); - if (*cp != '\0') { - fprintf(stderr, - "Bad argument %s to -t option; must be numeric\n", - optarg); - usage(); - } - trackno = ul; - break; - - default: - errs++; - } - argc -= optind; - argv += optind; - - if (argc != 0 || errs) - usage(); - /* check for mutually exclusive options */ - if (numids) { - if (fname || quiet || recover) - usage(); - } else { - if (trackno) - usage(); - } - - if (fname) { - if ((of = fopen(fname, "w")) == NULL) - err(EX_OSERR, "cannot create output file %s", fname); - } - - if ((fd = open(_devname, O_RDONLY)) == -1) - err(EX_OSERR, "cannot open device %s", _devname); - - return (numids? doreadid(fd, numids, trackno): doread(fd, of, _devname)); -} - -static int -doread(int fd, FILE *of, const char *_devname) -{ - char *trackbuf; - int rv, fdopts, recoverable, nerrs = 0; - unsigned int nbytes, tracksize, mediasize, secsize, n; - struct fdc_status fdcs; - struct fd_type fdt; - - if (ioctl(fd, FD_GTYPE, &fdt) == -1) - err(EX_OSERR, "ioctl(FD_GTYPE) failed -- not a floppy?"); - - secsize = 128 << fdt.secsize; - tracksize = fdt.sectrac * secsize; - mediasize = tracksize * fdt.tracks * fdt.heads; - if ((trackbuf = malloc(tracksize)) == NULL) - errx(EX_TEMPFAIL, "out of memory"); - - if (!quiet) - fprintf(stderr, "Reading %d * %d * %d * %d medium at %s\n", - fdt.tracks, fdt.heads, fdt.sectrac, secsize, _devname); - - for (nbytes = 0; nbytes < mediasize;) { - if (lseek(fd, nbytes, SEEK_SET) != nbytes) - err(EX_OSERR, "cannot lseek()"); - rv = read(fd, trackbuf, tracksize); - if (rv == 0) { - /* EOF? */ - warnx("premature EOF after %u bytes", nbytes); - free(trackbuf); - return (EX_OK); - } - if ((unsigned)rv == tracksize) { - nbytes += rv; - if (!quiet) - fprintf(stderr, "%5d KB\r", nbytes / 1024); - fwrite(trackbuf, sizeof(unsigned char), rv, of); - fflush(of); - continue; - } - if (rv == -1) { - /* fall back reading one sector at a time */ - for (n = 0; n < tracksize; n += secsize) { - if (lseek(fd, nbytes, SEEK_SET) != nbytes) - err(EX_OSERR, "cannot lseek()"); - rv = read(fd, trackbuf, secsize); - if ((unsigned) rv == secsize) { - nbytes += rv; - if (!quiet) - fprintf(stderr, "%5d KB\r", - nbytes / 1024); - fwrite(trackbuf, sizeof(unsigned char), - rv, of); - fflush(of); - continue; - } - if (rv == -1) { - if (errno != EIO) { - if (!quiet) - putc('\n', stderr); - perror("non-IO error"); - free(trackbuf); - return (EX_OSERR); - } - if (ioctl(fd, FD_GSTAT, &fdcs) == -1) - errx(EX_IOERR, - "floppy IO error, but no FDC status"); - nerrs++; - recoverable = fdcs.status[2] & - NE7_ST2_DD; - if (!quiet) { - printstatus(&fdcs, 0); - fputs(" (", stderr); - if (!recoverable) - fputs("not ", stderr); - fputs("recoverable)", stderr); - } - if (!recover) { - if (!quiet) - putc('\n', stderr); - free(trackbuf); - return (EX_IOERR); - } - memset(trackbuf, fillbyte, secsize); - if (recoverable) { - fdopts |= FDOPT_NOERROR; - if (ioctl(fd, FD_SOPTS, - &fdopts) == -1) - err(EX_OSERR, - "ioctl(fd, FD_SOPTS, FDOPT_NOERROR)"); - rv = read(fd, trackbuf, - secsize); - if ((unsigned)rv != secsize) - err(EX_IOERR, - "read() with FDOPT_NOERROR still fails"); - fdopts &= ~FDOPT_NOERROR; - (void)ioctl(fd, FD_SOPTS, - &fdopts); - } - if (!quiet) { - if (recoverable) - fprintf(stderr, - ": recovered"); - else - fprintf(stderr, - ": dummy"); - fprintf(stderr, - " data @ %#x ... %#x\n", - nbytes, - nbytes + secsize - 1); - } - nbytes += secsize; - fwrite(trackbuf, sizeof(unsigned char), - secsize, of); - fflush(of); - continue; - } - errx(EX_OSERR, "unexpected read() result: %d", - rv); - } - } - if ((unsigned)rv < tracksize) { - /* should not happen */ - nbytes += rv; - if (!quiet) - fprintf(stderr, "\nshort after %5d KB\r", - nbytes / 1024); - fwrite(trackbuf, sizeof(unsigned char), rv, of); - fflush(of); - continue; - } - } - free(trackbuf); - if (!quiet) { - putc('\n', stderr); - if (nerrs) - fprintf(stderr, "%d error%s\n", - nerrs, nerrs > 1? "s": ""); - } - - return (nerrs? EX_IOERR: EX_OK); -} - -static int -doreadid(int fd, unsigned int numids, unsigned int trackno) -{ - int rv = 0; - unsigned int i; - struct fdc_readid info; - struct fdc_status fdcs; - struct fd_type fdt; - - if (ioctl(fd, FD_GTYPE, &fdt) == -1) - err(EX_OSERR, "ioctl(FD_GTYPE) failed -- not a floppy?"); - - for (i = 0; i < numids; i++) { - info.cyl = trackno / fdt.heads; - info.head = fdt.heads > 1? trackno % fdt.heads: 0; - if (ioctl(fd, FD_READID, &info) == 0) { - printf("C = %d, H = %d, R = %d, N = %d\n", - info.cyl, info.head, info.sec, info.secshift); - } else { - if (errno != EIO) { - perror("non-IO error"); - return (EX_OSERR); - } - if (ioctl(fd, FD_GSTAT, &fdcs) == -1) - errx(EX_IOERR, - "floppy IO error, but no FDC status"); - printstatus(&fdcs, 0); - putc('\n', stderr); - rv = EX_IOERR; - } - } - - return (rv); -} Index: usr.sbin/fdread/fdutil.h =================================================================== --- usr.sbin/fdread/fdutil.h +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2001 Joerg Wunsch - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - - -void printstatus(struct fdc_status *fdcsp, int terse); -void parse_fmt(const char *, enum fd_drivetype, - struct fd_type, struct fd_type *); -struct fd_type *get_fmt(int, enum fd_drivetype); -void print_fmt(struct fd_type); -int getnum(const char *, int *); -void getname(enum fd_drivetype, const char **, const char **); - Index: usr.sbin/fdread/fdutil.c =================================================================== --- usr.sbin/fdread/fdutil.c +++ /dev/null @@ -1,486 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2001 Joerg Wunsch - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include "fdutil.h" - -/* - * Decode the FDC status pointed to by `fdcsp', and print a textual - * translation to stderr. If `terse' is false, the numerical FDC - * register status is printed, too. - */ -void -printstatus(struct fdc_status *fdcsp, int terse) -{ - char msgbuf[100]; - - if (!terse) - fprintf(stderr, - "\nFDC status ST0=%#x ST1=%#x ST2=%#x C=%u H=%u R=%u N=%u:\n", - fdcsp->status[0] & 0xff, - fdcsp->status[1] & 0xff, - fdcsp->status[2] & 0xff, - fdcsp->status[3] & 0xff, - fdcsp->status[4] & 0xff, - fdcsp->status[5] & 0xff, - fdcsp->status[6] & 0xff); - - if ((fdcsp->status[0] & NE7_ST0_IC_RC) == 0) { - sprintf(msgbuf, "timeout"); - } else if ((fdcsp->status[0] & NE7_ST0_IC_RC) != NE7_ST0_IC_AT) { - sprintf(msgbuf, "unexcpted interrupt code %#x", - fdcsp->status[0] & NE7_ST0_IC_RC); - } else { - strcpy(msgbuf, "unexpected error code in ST1/ST2"); - - if (fdcsp->status[1] & NE7_ST1_EN) - strcpy(msgbuf, "end of cylinder (wrong format)"); - else if (fdcsp->status[1] & NE7_ST1_DE) { - if (fdcsp->status[2] & NE7_ST2_DD) - strcpy(msgbuf, "CRC error in data field"); - else - strcpy(msgbuf, "CRC error in ID field"); - } else if (fdcsp->status[1] & NE7_ST1_MA) { - if (fdcsp->status[2] & NE7_ST2_MD) - strcpy(msgbuf, "no address mark in data field"); - else - strcpy(msgbuf, "no address mark in ID field"); - } else if (fdcsp->status[2] & NE7_ST2_WC) - strcpy(msgbuf, "wrong cylinder (format mismatch)"); - else if (fdcsp->status[1] & NE7_ST1_ND) - strcpy(msgbuf, "no data (sector not found)"); - } - fputs(msgbuf, stderr); -} - -static struct fd_type fd_types_auto[1] = - { { 0,0,0,0,0,0,0,0,0,0,0,FL_AUTO } }; - - -static struct fd_type fd_types_288m[] = { -#if 0 - { FDF_3_2880 }, -#endif - { FDF_3_1722 }, - { FDF_3_1476 }, - { FDF_3_1440 }, - { FDF_3_1200 }, - { FDF_3_820 }, - { FDF_3_800 }, - { FDF_3_720 }, - { 0,0,0,0,0,0,0,0,0,0,0,0 } -}; - -static struct fd_type fd_types_144m[] = { - { FDF_3_1722 }, - { FDF_3_1476 }, - { FDF_3_1440 }, - { FDF_3_1200 }, - { FDF_3_820 }, - { FDF_3_800 }, - { FDF_3_720 }, - { 0,0,0,0,0,0,0,0,0,0,0,0 } -}; - -static struct fd_type fd_types_12m[] = { - { FDF_5_1200 }, - { FDF_5_1230 }, - { FDF_5_1480 }, - { FDF_5_1440 }, - { FDF_5_820 }, - { FDF_5_800 }, - { FDF_5_720 }, - { FDF_5_360 | FL_2STEP }, - { FDF_5_640 }, - { 0,0,0,0,0,0,0,0,0,0,0,0 } -}; - -static struct fd_type fd_types_720k[] = -{ - { FDF_3_720 }, - { 0,0,0,0,0,0,0,0,0,0,0,0 } -}; - -static struct fd_type fd_types_360k[] = -{ - { FDF_5_360 }, - { 0,0,0,0,0,0,0,0,0,0,0,0 } -}; - - -/* - * Parse a format string, and fill in the parameter pointed to by `out'. - * - * sectrac,secsize,datalen,gap,ncyls,speed,heads,f_gap,f_inter,offs2,flags[...] - * - * sectrac = sectors per track - * secsize = sector size in bytes - * datalen = length of sector if secsize == 128 - * gap = gap length when reading - * ncyls = number of cylinders - * speed = transfer speed 250/300/500/1000 KB/s - * heads = number of heads - * f_gap = gap length when formatting - * f_inter = sector interleave when formatting - * offs2 = offset of sectors on side 2 - * flags = +/-mfm | +/-2step | +/-perpend - * mfm - use MFM recording - * 2step - use 2 steps between cylinders - * perpend - user perpendicular (vertical) recording - * - * Any omitted value will be passed on from parameter `in'. - */ -void -parse_fmt(const char *s, enum fd_drivetype type, - struct fd_type in, struct fd_type *out) -{ - int i, j; - const char *cp; - char *s1; - - *out = in; - - for (i = 0;; i++) { - if (s == NULL) - break; - - if ((cp = strchr(s, ',')) == NULL) { - s1 = strdup(s); - if (s1 == NULL) - abort(); - s = 0; - } else { - s1 = malloc(cp - s + 1); - if (s1 == NULL) - abort(); - memcpy(s1, s, cp - s); - s1[cp - s] = 0; - - s = cp + 1; - } - if (strlen(s1) == 0) { - free(s1); - continue; - } - - switch (i) { - case 0: /* sectrac */ - if (getnum(s1, &out->sectrac)) - errx(EX_USAGE, - "bad numeric value for sectrac: %s", s1); - break; - - case 1: /* secsize */ - if (getnum(s1, &j)) - errx(EX_USAGE, - "bad numeric value for secsize: %s", s1); - if (j == 128) out->secsize = 0; - else if (j == 256) out->secsize = 1; - else if (j == 512) out->secsize = 2; - else if (j == 1024) out->secsize = 3; - else - errx(EX_USAGE, "bad sector size %d", j); - break; - - case 2: /* datalen */ - if (getnum(s1, &j)) - errx(EX_USAGE, - "bad numeric value for datalen: %s", s1); - if (j >= 256) - errx(EX_USAGE, "bad datalen %d", j); - out->datalen = j; - break; - - case 3: /* gap */ - if (getnum(s1, &out->gap)) - errx(EX_USAGE, - "bad numeric value for gap: %s", s1); - break; - - case 4: /* ncyls */ - if (getnum(s1, &j)) - errx(EX_USAGE, - "bad numeric value for ncyls: %s", s1); - if (j > 85) - errx(EX_USAGE, "bad # of cylinders %d", j); - out->tracks = j; - break; - - case 5: /* speed */ - if (getnum(s1, &j)) - errx(EX_USAGE, - "bad numeric value for speed: %s", s1); - switch (type) { - default: - abort(); /* paranoia */ - - case FDT_360K: - case FDT_720K: - if (j == 250) - out->trans = FDC_250KBPS; - else - errx(EX_USAGE, "bad speed %d", j); - break; - - case FDT_12M: - if (j == 300) - out->trans = FDC_300KBPS; - else if (j == 250) - out->trans = FDC_250KBPS; - else if (j == 500) - out->trans = FDC_500KBPS; - else - errx(EX_USAGE, "bad speed %d", j); - break; - - case FDT_288M: - if (j == 1000) - out->trans = FDC_1MBPS; - /* FALLTHROUGH */ - case FDT_144M: - if (j == 250) - out->trans = FDC_250KBPS; - else if (j == 500) - out->trans = FDC_500KBPS; - else - errx(EX_USAGE, "bad speed %d", j); - break; - } - break; - - case 6: /* heads */ - if (getnum(s1, &j)) - errx(EX_USAGE, - "bad numeric value for heads: %s", s1); - if (j == 1 || j == 2) - out->heads = j; - else - errx(EX_USAGE, "bad # of heads %d", j); - break; - - case 7: /* f_gap */ - if (getnum(s1, &out->f_gap)) - errx(EX_USAGE, - "bad numeric value for f_gap: %s", s1); - break; - - case 8: /* f_inter */ - if (getnum(s1, &out->f_inter)) - errx(EX_USAGE, - "bad numeric value for f_inter: %s", s1); - break; - - case 9: /* offs2 */ - if (getnum(s1, &out->offset_side2)) - errx(EX_USAGE, - "bad numeric value for offs2: %s", s1); - break; - - default: - if (strcmp(s1, "+mfm") == 0) - out->flags |= FL_MFM; - else if (strcmp(s1, "-mfm") == 0) - out->flags &= ~FL_MFM; - else if (strcmp(s1, "+auto") == 0) - out->flags |= FL_AUTO; - else if (strcmp(s1, "-auto") == 0) - out->flags &= ~FL_AUTO; - else if (strcmp(s1, "+2step") == 0) - out->flags |= FL_2STEP; - else if (strcmp(s1, "-2step") == 0) - out->flags &= ~FL_2STEP; - else if (strcmp(s1, "+perpnd") == 0) - out->flags |= FL_PERPND; - else if (strcmp(s1, "-perpnd") == 0) - out->flags &= ~FL_PERPND; - else - errx(EX_USAGE, "bad flag: %s", s1); - break; - } - free(s1); - } - - out->size = out->tracks * out->heads * out->sectrac; -} - -/* - * Print a textual translation of the drive (density) type described - * by `in' to stdout. The string uses the same form that is parseable - * by parse_fmt(). - */ -void -print_fmt(struct fd_type in) -{ - int secsize, speed; - - secsize = 128 << in.secsize; - switch (in.trans) { - case FDC_250KBPS: speed = 250; break; - case FDC_300KBPS: speed = 300; break; - case FDC_500KBPS: speed = 500; break; - case FDC_1MBPS: speed = 1000; break; - default: speed = 1; break; - } - - printf("%d,%d,%#x,%#x,%d,%d,%d,%#x,%d,%d", - in.sectrac, secsize, in.datalen, in.gap, in.tracks, - speed, in.heads, in.f_gap, in.f_inter, in.offset_side2); - if (in.flags & FL_MFM) - printf(",+mfm"); - if (in.flags & FL_2STEP) - printf(",+2step"); - if (in.flags & FL_PERPND) - printf(",+perpnd"); - if (in.flags & FL_AUTO) - printf(",+auto"); - putc('\n', stdout); -} - -/* - * Based on `size' (in kilobytes), walk through the table of known - * densities for drive type `type' and see if we can find one. If - * found, return it (as a pointer to static storage), otherwise return - * NULL. - */ -struct fd_type * -get_fmt(int size, enum fd_drivetype type) -{ - int i, n; - struct fd_type *fdtp; - - switch (type) { - default: - return (0); - - case FDT_360K: - fdtp = fd_types_360k; - n = sizeof fd_types_360k / sizeof(struct fd_type); - break; - - case FDT_720K: - fdtp = fd_types_720k; - n = sizeof fd_types_720k / sizeof(struct fd_type); - break; - - case FDT_12M: - fdtp = fd_types_12m; - n = sizeof fd_types_12m / sizeof(struct fd_type); - break; - - case FDT_144M: - fdtp = fd_types_144m; - n = sizeof fd_types_144m / sizeof(struct fd_type); - break; - - case FDT_288M: - fdtp = fd_types_288m; - n = sizeof fd_types_288m / sizeof(struct fd_type); - break; - } - - if (size == -1) - return fd_types_auto; - - for (i = 0; i < n; i++, fdtp++) { - fdtp->size = fdtp->sectrac * fdtp->heads * fdtp->tracks; - if (((128 << fdtp->secsize) * fdtp->size / 1024) == size) - return (fdtp); - } - return (0); -} - -/* - * Parse a number from `s'. If the string cannot be converted into a - * number completely, return -1, otherwise 0. The result is returned - * in `*res'. - */ -int -getnum(const char *s, int *res) -{ - unsigned long ul; - char *cp; - - ul = strtoul(s, &cp, 0); - if (*cp != '\0') - return (-1); - - *res = (int)ul; - return (0); -} - -/* - * Return a short name and a verbose description for the drive - * described by `t'. - */ -void -getname(enum fd_drivetype t, const char **name, const char **descr) -{ - - switch (t) { - default: - *name = "unknown"; - *descr = "unknown drive type"; - break; - - case FDT_360K: - *name = "360K"; - *descr = "5.25\" double-density"; - break; - - case FDT_12M: - *name = "1.2M"; - *descr = "5.25\" high-density"; - break; - - case FDT_720K: - *name = "720K"; - *descr = "3.5\" double-density"; - break; - - case FDT_144M: - *name = "1.44M"; - *descr = "3.5\" high-density"; - break; - - case FDT_288M: - *name = "2.88M"; - *descr = "3.5\" extra-density"; - break; - } -} Index: usr.sbin/fdwrite/Makefile =================================================================== --- usr.sbin/fdwrite/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# ---------------------------------------------------------------------------- -# "THE BEER-WARE LICENSE" (Revision 42): -# wrote this file. As long as you retain this notice you -# can do whatever you want with this stuff. If we meet some day, and you think -# this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp -# ---------------------------------------------------------------------------- -# -# $FreeBSD$ - -PROG= fdwrite - -.include Index: usr.sbin/fdwrite/Makefile.depend =================================================================== --- usr.sbin/fdwrite/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.sbin/fdwrite/fdwrite.1 =================================================================== --- usr.sbin/fdwrite/fdwrite.1 +++ /dev/null @@ -1,129 +0,0 @@ -.\" -.\" ---------------------------------------------------------------------------- -.\" "THE BEER-WARE LICENSE" (Revision 42): -.\" wrote this file. As long as you retain this notice you -.\" can do whatever you want with this stuff. If we meet some day, and you think -.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp -.\" ---------------------------------------------------------------------------- -.\" -.\" $FreeBSD$ -.\" -.\" -.Dd September 16, 1993 -.Dt FDWRITE 1 -.Os -.Sh NAME -.Nm fdwrite -.Nd format and write floppy disks -.Sh SYNOPSIS -.Nm -.Op Fl v -.Op Fl y -.Op Fl f Ar inputfile -.Op Fl d Ar device -.Sh DESCRIPTION -The -.Nm -utility formats and writes one and more floppy disks. -Any floppy disk device capable of formatting can be used. -.Pp -The -.Nm -utility will ask the user -(on -.Pa /dev/tty ) -to insert a new floppy and press return. -The device will then be opened, and queried for its parameters, -then each track will be formatted, written with data from the -.Ar inputfile , -read back and compared. -When the floppy disk is filled, the process is repeated, with the next disk. -This continues until the program is interrupted or EOF is encountered on the -.Ar inputfile . -.Pp -The options are as follows: -.Bl -tag -width 10n -offset indent -.It Fl v -Toggle verbosity on stdout. -Default is ``on''. -After -.Ar device -is opened first time the format will be printed. -During operation progress will be reported with the number of tracks -remaining on the current floppy disk, and the letters I, Z, F, W, -R and C, which indicates completion of Input, Zero-fill, Format -Write, Read and Compare of current track respectively. -.It Fl y -Do not ask for presence of a floppy disk in the drive. -This non-interactive flag -is useful for shell scripts. -.It Fl f Ar inputfile -Input file to read. -If none is given, stdin is assumed. -.It Fl d Ar device -The name of the floppy device to write to. -Default is -.Pa /dev/fd0 . -.El -.Pp -The -.Nm -utility actually closes the -.Ar device -while it waits for the user to press return, -it is thus quite possible to use the drive for other purposes at this -time and later resume writing with the next floppy. -.Pp -The parameters returned from -.Ar device -are used for formatting. -If custom formatting is needed, please use -.Xr fdformat 1 -instead. -.Sh EXAMPLES -The -.Nm -utility -was planned as a tool to make life easier when writing a set of floppies, -one such use could be to write a tar-archive: -.Pp -.Dl tar cf - . | gzip -9 | fdwrite -d /dev/fd0.1720 -v -.Pp -The main difference from using -.Xr tar 1 Ns 's -multivolume facility is of course the formatting of the floppies, which -here is done on the fly, -thus reducing the amount of work for the floppy-jockey. -.Sh SEE ALSO -.Xr fdformat 1 -.Sh HISTORY -The -.Nm -utility was written while waiting for ``make world'' to complete. -Some of the code was taken from -.Xr fdformat 1 . -.Sh AUTHORS -The program has been contributed by -.An Poul-Henning Kamp Aq Mt phk@FreeBSD.org . -.Sh BUGS -Diagnostics are less than complete at present. -.Pp -If a floppy is sick, and the -.Ar inputfile -is seekable, it should ask the user to frisbee the disk, insert -another, and rewind to the right spot and continue. -.Pp -This concept could be extended to cover non-seekable input also -by employing a temporary file. -.Pp -An option (defaulting to zero) should allow the user to ask for -retries in case of failure. -.Pp -At present a suitable tool for reading back a multivolume set -of floppies is missing. -Programs like -.Xr tar 1 -for instance, will do the job, if the data has not been compressed. -One can always trust -.Xr dd 1 -to help out in this situation of course. Index: usr.sbin/fdwrite/fdwrite.c =================================================================== --- usr.sbin/fdwrite/fdwrite.c +++ /dev/null @@ -1,198 +0,0 @@ -/*- - * SPDX-License-Identifier: Beerware - * - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $FreeBSD$ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int -format_track(int fd, int cyl, int secs, int head, int rate, - int gaplen, int secsize, int fill, int interleave) -{ - struct fd_formb f; - register int i,j; - int il[100]; - - memset(il,0,sizeof il); - for(j = 0, i = 1; i <= secs; i++) { - while(il[(j%secs)+1]) j++; - il[(j%secs)+1] = i; - j += interleave; - } - - f.format_version = FD_FORMAT_VERSION; - f.head = head; - f.cyl = cyl; - f.transfer_rate = rate; - - f.fd_formb_secshift = secsize; - f.fd_formb_nsecs = secs; - f.fd_formb_gaplen = gaplen; - f.fd_formb_fillbyte = fill; - for(i = 0; i < secs; i++) { - f.fd_formb_cylno(i) = cyl; - f.fd_formb_headno(i) = head; - f.fd_formb_secno(i) = il[i+1]; - f.fd_formb_secsize(i) = secsize; - } - return ioctl(fd, FD_FORM, (caddr_t)&f); -} - -static void -usage(void) -{ - fprintf(stderr, "usage: fdwrite [-v] [-y] [-f inputfile] [-d device]\n"); - exit(2); -} - -int -main(int argc, char **argv) -{ - int inputfd = -1, c, fdn = 0, i,j,fd; - int bpt, verbose=1, nbytes=0, track; - int interactive = 1; - const char *device= "/dev/fd0"; - char *trackbuf = 0,*vrfybuf = 0; - struct fd_type fdt; - FILE *tty; - - setbuf(stdout,0); - while((c = getopt(argc, argv, "d:f:vy")) != -1) - switch(c) { - case 'd': /* Which drive */ - device = optarg; - break; - - case 'f': /* input file */ - if (inputfd >= 0) - close(inputfd); - inputfd = open(optarg,O_RDONLY); - if (inputfd < 0) - err(1, "%s", optarg); - break; - - case 'v': /* Toggle verbosity */ - verbose = !verbose; - break; - - case 'y': /* Don't confirm? */ - interactive = 0; - break; - - case '?': default: - usage(); - } - - if (inputfd < 0) - inputfd = 0; - - if (!isatty(1)) - interactive = 0; - - if(optind < argc) - usage(); - - tty = fopen(_PATH_TTY,"r+"); - if(!tty) - err(1, _PATH_TTY); - setbuf(tty,0); - - for(j=1;j > 0;) { - fdn++; - if (interactive) { - fprintf(tty, - "Please insert floppy #%d in drive %s and press return >", - fdn,device); - while(1) { - i = getc(tty); - if(i == '\n') break; - } - } - - if((fd = open(device, O_RDWR)) < 0) - err(1, "%s", device); - - if(ioctl(fd, FD_GTYPE, &fdt) < 0) - errx(1, "not a floppy disk: %s", device); - - bpt = fdt.sectrac * (1<= 0 && j= 0 && j