From nobody@FreeBSD.org  Wed May 17 03:05:40 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 0DA5A16A403
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 17 May 2006 03:05:40 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id A6F5143D49
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 17 May 2006 03:05:38 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k4H35c3Z097036
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 17 May 2006 03:05:38 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k4H35bA8097035;
	Wed, 17 May 2006 03:05:37 GMT
	(envelope-from nobody)
Message-Id: <200605170305.k4H35bA8097035@www.freebsd.org>
Date: Wed, 17 May 2006 03:05:37 GMT
From: "Scott G. Taylor" <staylor@mrynet.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Patch to add zero-sector and spanned-side floppy support.
X-Send-Pr-Version: www-2.3

>Number:         97381
>Category:       kern
>Synopsis:       [fdc] [patch] 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:  Sat Jun 03 01:50:01 GMT 2006
>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@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:
