svn commit: r254937 - head/sys/dev/fdc

Joerg Wunsch joerg at FreeBSD.org
Mon Aug 26 21:15:51 UTC 2013


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);
 	}


More information about the svn-src-all mailing list