kern/97381: Patch to add zero-sector and spanned-side floppy support.

Scott G. Taylor staylor at mrynet.com
Wed May 17 03:10:14 UTC 2006


>Number:         97381
>Category:       kern
>Synopsis:       Patch to add zero-sector and spanned-side floppy support.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 17 03:10:11 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Scott G. Taylor
>Release:        7.0-CURRENT APR 30 2006
>Organization:
>Environment:
FreeBSD mrynet.com 7.0-CURRENT FreeBSD 7.0-CURRENT #6: Sun Apr 30 19:06:33 CDT 2006     staylor at mrynet.com:/usr/obj/usr/src/sys/MRYMACH  i386

>Description:
In order to support accessibility for older floppy formats (in particular Kaypro 4/10 DSDD and some music synthesizers), I submit the following patches to FreeBSD 7.0-CURRENT for consideration.

The patch allows two new modifiers to the floppy format handling in the fdc.c
driver.  1) allow sector numbers to start with 0 (zero) instead of 1 (one).  2) To allow the second-side of two-sided floppies to be physically written as an extension of the first side; that is, sectors on side two have a sector ID of head 0 (zero) and sector numbers continue from where side 1 (one) left off, as is the case with Kaypro 4/10 floppies.

I have provided a patch that modifies sys/dev/fdc/fdc.c, sys/sys/fdcio.h, usr.sbin/fdread/fdread.c, usr.sbin/fdcontrol/fdcontrol.c and usr.sbin/fdcontrol/fdcontrol.8.

These patches do not affect the current operation of the floppy; that is, they are additional functionality that, unless optionally set into use, do not affect operation of the device.

Please consider this patch for future inclusion in FreeBSD to expand the usefulness of the floppy driver.
>How-To-Repeat:
Attempt to set the floppy format via fdcontrol(8) and read a floppy written on an Kaypro 4/10 (DSDD, 2 heads, 10 sector, 512 bytes, 40 cylinders).  The first side of track 1 can be read, but track two cannot because the sector IDs identify the head as 0 (zero) and sector numbers are in the range or 10..19.
>Fix:
Applying the following patch provides the +span/-span and +zerosect/-zerosect options to the floppy driver (usually via fdcontrol(8)) to accomodate the above-mentioned issue.

--- fdcio.h-ORIG        Wed Feb  8 22:52:05 2006
+++ fdcio.h     Fri May 12 02:36:49 2006
@@ -97,6 +97,9 @@
 #define FL_2STEP       0x0002          /* 2 steps between cylinders */
 #define FL_PERPND      0x0004          /* perpendicular recording */
 #define FL_AUTO                0x0008          /* autodetect format */
+#define FL_ZEROSECT    0x0010          /* Sector numbers begin with zero */
+#define FL_SPAN                0x0020          /* Sector numbers on side 2  */
+                                       /* continue from side 1      */
 };
 
 struct fdc_status {

--- fdc.c-DIST  Tue May 16 18:22:13 2006
+++ fdc.c       Tue May 16 20:47:44 2006
@@ -734,6 +734,7 @@
        int i, nsect;
        int st0, st3, cyl, mfm, steptrac, cylinder, descyl, sec;
        int head;
+       int loghead, logsec, logsectrac;
        static int need_recal;
        struct fdc_readid *idp;
        struct fd_formb *finfo;
@@ -909,7 +910,7 @@
        sec = bp->bio_pblkno % i;
        nsect = i - sec;
        head = sec / fd->ft->sectrac;
-       sec = sec % fd->ft->sectrac + 1;
+       sec = sec % fd->ft->sectrac;
 
        /* If everything is going swimmingly, use multisector xfer */
        if (fdc->retry == 0 && bp->bio_cmd & (BIO_READ|BIO_WRITE)) {
@@ -969,6 +970,36 @@
        }
        fd->track = cylinder;
 
+       /*
+        * If offset_side2 is set, it should indicate the logical sector
+        * number offset for the sectors on side 2.  This really should
+        * imply FL_SPAN, but it is unknown if there are floppy formats
+        * that don't actually use logical head numbers of zero on side 2.
+        * When in effect, offset_side2 is normally set to sectrac, or
+        * sectrac-1 when FL_ZEROSECT is in effect.
+        *
+        * If FL_SPAN flag set, side 2 sector IDs will have their
+        * cylinders and heads identified as side 1's.  The sector
+        * numbers continue from the last on side 0.  Effectively,
+        * there are half as many tracks, but twice as many sectors
+        * per track.  offset_side2 should be set with FL_SPAN.
+        *
+        * If FL_ZEROSECT is set, the first sector number is 0 (zero)
+        * rather than 1 (one).
+        */
+
+       loghead = head;
+       logsectrac = fd->ft->sectrac;
+       logsec = sec;
+       if ((fd->ft->flags & FL_ZEROSECT) == 0)
+               logsec = logsec + 1;
+       if (head != 0 && fd->ft->offset_side2 != 0) {
+               logsec = logsec + fd->ft->offset_side2;
+               logsectrac = fd->ft->sectrac * 2 + ((fd->ft->flags & FL_ZEROSECT) != 0);
+       }
+       if (head != 0 && (fd->ft->flags & FL_SPAN))
+               loghead = 0;
+
        if (debugflags & 8)
                printf("op %x bn %ju siz %u ptr %p retry %d\n",
                    bp->bio_cmd, bp->bio_pblkno, fd->fd_iosize,
@@ -1021,11 +1052,11 @@
                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->track,                  /* logical track */
+                   loghead,                    /* logical head */
+                   logsec,                     /* logical sector */
                    fd->ft->secsize,            /* sector size */
-                   fd->ft->sectrac,            /* sectors/track */
+                   logsectrac,                 /* track's hightest sector number */
                    fd->ft->gap,                /* gap size */
                    fd->ft->datalen,            /* data length */
                    0))
@@ -1036,11 +1067,11 @@
                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->track,                  /* logical track */
+                   loghead,                    /* logical head */
+                   logsec,                     /* logical sector */
                    fd->ft->secsize,            /* sector size */
-                   fd->ft->sectrac,            /* sectors/track */
+                   logsectrac,                 /* track's highest sector number */
                    fd->ft->gap,                /* gap size */
                    fd->ft->datalen,            /* data length */
                    0))

diff -ruN fdcontrol.c-DIST fdcontrol.c
--- fdcontrol.c-DIST    Wed Oct 26 17:23:52 2005
+++ fdcontrol.c Tue May 16 22:04:42 2006
@@ -197,6 +197,14 @@
                                printf("%sAUTO", s);
                                s = ",";
                        }
+                       if (ft.flags & FL_ZEROSECT) {
+                               printf("%sZEROSECT", s);
+                               s = ",";
+                       }
+                       if (ft.flags & FL_SPAN) {
+                               printf("%sSPAN", s);
+                               s = ",";
+                       }
                        printf(">\n");
                } else {
                        print_fmt(ft);

--- fdcontrol.8-DIST    Fri Jul  2 18:12:41 2004
+++ fdcontrol.8 Tue May 16 20:54:49 2006
@@ -250,6 +250,19 @@
 supported).
 .It Cm -perpend
 Use longitudinal recording.
+.It Cm +zerosect
+Use a starting sector of zero rather than one.
+.It Cm -zerosect
+Use a starting sector of one rather than zero (default)
+.It Cm +span
+Sector ID numbers on side two of two-sided media continue from side one
+,i.e. if sector ID numbers  on side 1 are numbered 1 to 10, sectors on side
+2 are numbered 11 to 20; the logical head number stored in the sector ID
+will be zero.
+.It Cm -span
+Sector ID numbers on side two of two-sided media start over from the first
+sector number and the logical head in the sector ID matches the physical
+head.
 .El
 .El
 .Pp

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list