Author: joerg
Date: Mon Aug 26 21:15:50 2013
New Revision: 254937
URL: http://svnweb.freebsd.org/changeset/base/254937

Log:
  Reimplement the FDOPT_NOERROR feature that was kicked out in r134081.
  
  It is needed for fdread(1) in order to be able to recover from CRC
  errors in the data field of a floppy sector (by returning the sector
  data that failed CRC, rather than inventing dummy data).
  
  When closing the device, clear all transient device options.
  
  MFC after:    1 week

Modified:
  head/sys/dev/fdc/fdc.c

Modified: head/sys/dev/fdc/fdc.c
==============================================================================
--- head/sys/dev/fdc/fdc.c      Mon Aug 26 20:39:02 2013        (r254936)
+++ head/sys/dev/fdc/fdc.c      Mon Aug 26 21:15:50 2013        (r254937)
@@ -761,10 +761,13 @@ fdc_worker(struct fdc_data *fdc)
        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;
@@ -1090,7 +1093,10 @@ fdc_worker(struct fdc_data *fdc)
                            fdc->status[3], fdc->status[4], fdc->status[5]);
                }
                retry_line = __LINE__;
-               return (1);
+               if (fd->options & FDOPT_NOERROR)
+                       override_error = 1;
+               else
+                       return (1);
        }
        /* All OK */
        switch(bp->bio_cmd) {
@@ -1111,10 +1117,16 @@ fdc_worker(struct fdc_data *fdc)
                bp->bio_resid -= fd->fd_iosize;
                bp->bio_completed += fd->fd_iosize;
                fd->fd_ioptr += fd->fd_iosize;
-               /* Since we managed to get something done, reset the retry */
-               fdc->retry = 0;
-               if (bp->bio_resid > 0)
-                       return (0);
+               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;
@@ -1406,6 +1418,7 @@ fd_access(struct g_provider *pp, int r, 
        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);
        }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to