From eugen@grosbein.pp.ru  Sat Sep 22 05:45:49 2007
Return-Path: <eugen@grosbein.pp.ru>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 9DD4916A419
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 22 Sep 2007 05:45:49 +0000 (UTC)
	(envelope-from eugen@grosbein.pp.ru)
Received: from grosbein.pp.ru (grgw.svzserv.kemerovo.su [213.184.64.166])
	by mx1.freebsd.org (Postfix) with ESMTP id E4BE213C46E
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 22 Sep 2007 05:45:48 +0000 (UTC)
	(envelope-from eugen@grosbein.pp.ru)
Received: from grosbein.pp.ru (localhost [127.0.0.1])
	by grosbein.pp.ru (8.14.1/8.14.1) with ESMTP id l8M5jluj002239
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 22 Sep 2007 13:45:47 +0800 (KRAST)
	(envelope-from eugen@grosbein.pp.ru)
Received: (from eugen@localhost)
	by grosbein.pp.ru (8.14.1/8.14.1/Submit) id l8M5jlrt002238;
	Sat, 22 Sep 2007 13:45:47 +0800 (KRAST)
	(envelope-from eugen)
Message-Id: <200709220545.l8M5jlrt002238@grosbein.pp.ru>
Date: Sat, 22 Sep 2007 13:45:47 +0800 (KRAST)
From: Eugene Grosbein <eugen@grosbein.pp.ru>
Reply-To: Eugene Grosbein <eugen@grosbein.pp.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [fdc] [patch] reintroduce FD_NO_CHLINE flag for fdc(4)
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         116538
>Category:       kern
>Synopsis:       [fdc] [patch] reintroduce FD_NO_CHLINE flag for fdc(4)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    jkim
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Sep 22 05:50:01 GMT 2007
>Closed-Date:    Mon Nov 17 19:25:43 UTC 2008
>Last-Modified:  Wed Jan 21 17:40:01 UTC 2009
>Originator:     Eugene Grosbein
>Release:        FreeBSD 6.2-STABLE i386
>Organization:
Svyaz-Service JSC
>Environment:
System: FreeBSD grosbein.pp.ru 6.2-STABLE FreeBSD 6.2-STABLE #2: Sun Sep 16 16:54:23 KRAST 2007 eu@grosbein.pp.ru:/home/obj/usr/local/src/sys/DADV i386

>Description:
	Workaround for floppy disk drives missing media change indication
	support (FD_NO_CHLINE flag for fdc(4)) was removed in 2001 after
	media change detection was fixed in fdc(4) and believed to work
	reliably.

	This is no longer true these days when new motherboards
	have FDD controlles that miss Configuration Control Register,
	so fdc(4) cannot detect media change. We need FD_NO_CHLINE flag
	again until fdc(4) fixed. See commit log message for
	sys/dev/fdc/fdc.c,v.1.307.2.4 for additional details.

>How-To-Repeat:

	Take motherboard which FDD controller does not have CCR.
	Modern Intel desktop motherboards fit, also you may get
	more examples from
	http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/103841

	Boot kernel with fdc(4) compiled in or kldload fdc.ko
	when there is write-protected floppy in the drive.
	Then do:

echo -n > /dev/fd0

	You'll get 'Read-only file system' error.
	Remove disk from the drive, uprotect it, insert back
	and repeat 'echo -n > /dev/fd0'. You'll get the same error
	because media change detection does not work.

	For real example replace 'echo -n' with 'fdformat' that also
	opens device for writing. So it's impossible to format floppy drive
	until reboot if there was write-protected disk in the drive
	and the boot time.

	Note that fdc(4) man page still mentions 0x10 flag that 
	was ever used as valuse for FD_NO_CHLINE flag it does not exist
	in the code many years. More, the value 0x10 is now used by fdc(4)
	internally for other means and we need to choose another value.

>Fix:

--- share/man/man4/fdc.4.orig	2007-09-16 16:23:27.000000000 +0800
+++ share/man/man4/fdc.4	2007-09-16 16:23:34.000000000 +0800
@@ -101,7 +101,7 @@
 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
+.Ar 0x40
 (causing each call to
 .Xr open 2
 to perform the autodetection).
@@ -98,6 +98,8 @@
 				 * and fd1 */
 #define FD_NO_PROBE	0x20	/* don't probe drive (seek test), just
 				 * assume it is there */
+#define FD_NO_CHLINE	0x40	/* drive does not support changeline
+				* aka. unit attention */
 
 /*
  * Things that could conceiveably considered parameters or tweakables
@@ -827,7 +829,8 @@
 
 	if (bp->bio_cmd & BIO_PROBE) {
 
-		if (!(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
+		if (!(fd->flags & FD_NO_CHLINE) &&
+		    !(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
 			return (fdc_biodone(fdc, 0));
 
 		/*


>Release-Note:
>Audit-Trail:

From: Eugene Grosbein <eugen@grosbein.pp.ru>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/116538: [fdc] [patch] reintroduce FD_NO_CHLINE flag for fdc(4)
Date: Sat, 22 Sep 2007 13:55:31 +0800

 Sorry, I've attached malformed version of patch. The correct line follows.
 Another note, one may verify that is works only after applying another
 patch from http://www.freebsd.org/cgi/query-pr.cgi?pr=116536,
 because fdc(4) ignores per-drive hints for now. After all, you may
 use 'hint.fd.0.flags=0x40' to enable FD_NO_CHLINE.
 
 --- share/man/man4/fdc.4.orig	2007-09-16 16:23:27.000000000 +0800
 +++ share/man/man4/fdc.4	2007-09-16 16:23:34.000000000 +0800
 @@ -101,7 +101,7 @@
  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
 +.Ar 0x40
  (causing each call to
  .Xr open 2
  to perform the autodetection).
 --- sys/dev/fdc/fdc.c.orig	2007-09-15 16:53:23.000000000 +0800
 +++ sys/dev/fdc/fdc.c	2007-09-16 16:26:07.000000000 +0800
 @@ -98,6 +98,8 @@
  				 * and fd1 */
  #define FD_NO_PROBE	0x20	/* don't probe drive (seek test), just
  				 * assume it is there */
 +#define FD_NO_CHLINE	0x40	/* drive does not support changeline
 +				* aka. unit attention */
  
  /*
   * Things that could conceiveably considered parameters or tweakables
 @@ -827,7 +829,8 @@
  
  	if (bp->bio_cmd & BIO_PROBE) {
  
 -		if (!(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
 +		if (!(fd->flags & FD_NO_CHLINE) &&
 +		    !(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
  			return (fdc_biodone(fdc, 0));
  
  		/*

From: Bruce Evans <brde@optusnet.com.au>
To: Eugene Grosbein <eugen@grosbein.pp.ru>
Cc: FreeBSD-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org
Subject: Re: kern/116538: [fdc] [patch] reintroduce FD_NO_CHLINE flag for
 fdc(4)
Date: Sat, 22 Sep 2007 18:44:55 +1000 (EST)

 On Sat, 22 Sep 2007, Eugene Grosbein wrote:
 
 >> Description:
 > 	Workaround for floppy disk drives missing media change indication
 > 	support (FD_NO_CHLINE flag for fdc(4)) was removed in 2001 after
 > 	media change detection was fixed in fdc(4) and believed to work
 > 	reliably.
 >
 > 	This is no longer true these days when new motherboards
 > 	have FDD controlles that miss Configuration Control Register,
 > 	so fdc(4) cannot detect media change. We need FD_NO_CHLINE flag
 > 	again until fdc(4) fixed. See commit log message for
 > 	sys/dev/fdc/fdc.c,v.1.307.2.4 for additional details.
 
 What happens for older FDD controllers that don't support the change
 line, and hardware with a broken change line?
 
 > 	Note that fdc(4) man page still mentions 0x10 flag that
 > 	was ever used as valuse for FD_NO_CHLINE flag it does not exist
 > 	in the code many years. More, the value 0x10 is now used by fdc(4)
 > 	internally for other means and we need to choose another value.
 
 No, the internal flag was always used by fdc(4), and has nothing to do
 with the device flag.  See my reply to your PR about broken device flags
 
 >> Fix:
 >
 > --- share/man/man4/fdc.4.orig	2007-09-16 16:23:27.000000000 +0800
 > +++ share/man/man4/fdc.4	2007-09-16 16:23:34.000000000 +0800
 > @@ -101,7 +101,7 @@
 > 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
 > +.Ar 0x40
 > (causing each call to
 > .Xr open 2
 > to perform the autodetection).
 
 This shouldn't be changed.
 
 > @@ -98,6 +98,8 @@
 > 				 * and fd1 */
 > #define FD_NO_PROBE	0x20	/* don't probe drive (seek test), just
 > 				 * assume it is there */
 > +#define FD_NO_CHLINE	0x40	/* drive does not support changeline
 > +				* aka. unit attention */
 >
 > /*
 >  * Things that could conceiveably considered parameters or tweakables
 
 Add it back where it was, with correct identation.
 
 > @@ -827,7 +829,8 @@
 >
 > 	if (bp->bio_cmd & BIO_PROBE) {
 >
 > -		if (!(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
 > +		if (!(fd->flags & FD_NO_CHLINE) &&
 > +		    !(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
 > 			return (fdc_biodone(fdc, 0));
 >
 > 		/*
 >
 
 Use a device_get_flags() call here, not quite where it was.  Old code
 was obfuscated by using copying the result into a local variable much
 earlier, and then using the variable at most once (in the FNONBLOCK
 case).
 
 BTW, what happens with no FNONBLOCK/O_NONBLOCK in the whole driver
 now?  FNONBLOCK used to be used to avoid excessive probing on open.
 Some opens must succeed even if the media is unreadable so that the
 drive can be controlled (mainly for formatting media that is present
 but not readable).  cd drivers still handle this poorly, not using
 O_NONBLOCK, but fd can be simpler because there is less to control
 if there is no media.
 
 Bruce

From: Eugene Grosbein <eugen@grosbein.pp.ru>
To: bug-followup@freebsd.org
Cc: Bruce Evans <brde@optusnet.com.au>
Subject: Re: kern/116538: [fdc] [patch] reintroduce FD_NO_CHLINE flag for fdc(4)
Date: Tue, 25 Sep 2007 01:12:15 +0800

 On at, 22 Sep 2007, Bruce Evans wrote:
 
 >> We need FD_NO_CHLINE flag again until fdc(4) fixed.
 > What happens for older FDD controllers that don't support the change
 > line, and hardware with a broken change line?
 
 I have no such hardware and cannot check. I suppose, it suffers
 from the same problem.
 
 [skip]
 
 Concerning the style remark you have done, feel free to commit version
 you like. I'm not a committer, anyway :-)
 
 Eugene Grosbein

From: Bruce Evans <brde@optusnet.com.au>
To: Eugene Grosbein <eugen@grosbein.pp.ru>
Cc: bug-followup@FreeBSD.org, Bruce Evans <brde@optusnet.com.au>
Subject: Re: kern/116538: [fdc] [patch] reintroduce FD_NO_CHLINE flag for
 fdc(4)
Date: Tue, 25 Sep 2007 05:25:02 +1000 (EST)

 On Tue, 25 Sep 2007, Eugene Grosbein wrote:
 
 > On at, 22 Sep 2007, Bruce Evans wrote:
 >
 >>> We need FD_NO_CHLINE flag again until fdc(4) fixed.
 >> What happens for older FDD controllers that don't support the change
 >> line, and hardware with a broken change line?
 >
 > I have no such hardware and cannot check. I suppose, it suffers
 > from the same problem.
 
 The hardware is easy to break :-).
 
 I think there's a difference between controllers without support and
 controllers+hardware that the driver doesn't understand.  I hope there
 is only a problem with the latter.
 
 > [skip]
 >
 > Concerning the style remark you have done, feel free to commit version
 > you like. I'm not a committer, anyway :-)
 
 Sorry, I won't be committing anything to fdc.
 
 Bruce

From: Gavin Atkinson <gavin@FreeBSD.org>
To: bug-followup@FreeBSD.org
Cc: Eugene Grosbein <eugen@grosbein.pp.ru>
Subject: Re: kern/116538: [fdc] [patch] reintroduce FD_NO_CHLINE flag for
 fdc(4)
Date: Sat, 16 Aug 2008 13:08:04 +0100 (BST)

 Can you try this patch please?
 
 Index: src/sys/dev/fdc/fdc.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/fdc/fdc.c,v
 retrieving revision 1.320
 diff -u -r1.320 fdc.c
 --- src/sys/dev/fdc/fdc.c	11 Jan 2008 16:50:52 -0000	1.320
 +++ src/sys/dev/fdc/fdc.c	16 Aug 2008 12:02:13 -0000
 @@ -97,6 +97,8 @@
   				 * 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 */
 
 @@ -837,7 +839,8 @@
 
   	if (bp->bio_cmd & BIO_PROBE) {
 
 -		if (!(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
 +		if (!(device_get_flags(fd->dev) & FD_NO_CHLINE) &&
 +		    !(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
   			return (fdc_biodone(fdc, 0));
 
   		/*
State-Changed-From-To: open->suspended 
State-Changed-By: gavin 
State-Changed-When: Thu Aug 21 12:55:25 UTC 2008 
State-Changed-Why:  
Mark suspended, mail to submitter bounces with 
"450 4.0.0 <eugen@grosbein.pp.ru>... You are still not in my white list. Please try later." 
and I never made it into their whitelist after five days. 

However, I suspect the patch will resolve their problem, so mark 
suspended until they, or someone else, can test the patch. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116538 
State-Changed-From-To: suspended->feedback 
State-Changed-By: gavin 
State-Changed-When: Thu Aug 21 15:57:10 UTC 2008 
State-Changed-Why:  
Unsuspend, submitter successfully receives emails from GNATS.  To 
submitter: there is a patch in the PR audit trail that I believe is a 
more correct fix for your problems.  Could you try it please?  Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116538 
State-Changed-From-To: feedback->open 
State-Changed-By: gavin 
State-Changed-When: Thu Aug 21 20:34:02 UTC 2008 
State-Changed-Why:  
Mark as open: submitter confirms that this patch fixes the issue for them. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116538 
State-Changed-From-To: open->analyzed 
State-Changed-By: linimon 
State-Changed-When: Thu Aug 21 22:22:12 UTC 2008 
State-Changed-Why:  
Sounds like 'analyzed' might be better here. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116538 
Responsible-Changed-From-To: freebsd-bugs->jkim 
Responsible-Changed-By: bz 
Responsible-Changed-When: Fri Oct 17 14:56:01 UTC 2008 
Responsible-Changed-Why:  
Hi, 
seems you last touched fdc regarding registers etc. 
Could you have a look at the patch? 
Thanks 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116538 

From: Jung-uk Kim <jkim@FreeBSD.org>
To: bz@FreeBSD.org,
 Eugene Grosbein <eugen@grosbein.pp.ru>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/116538: [fdc] [patch] reintroduce FD_NO_CHLINE flag for fdc(4)
Date: Tue, 28 Oct 2008 13:06:18 -0400

 --Boundary-00=_Ma0BJ/rsQrMDFhF
 Content-Type: text/plain;
   charset="iso-8859-1"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline
 
 This patch seems incomplete.  Please try the attached patch instead.
 
 Sorry for the delay,
 
 Jung-uk Kim
 
 --Boundary-00=_Ma0BJ/rsQrMDFhF
 Content-Type: text/x-diff;
   charset="iso-8859-1";
   name="fdc.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
 	filename="fdc.diff"
 
 --- sys/dev/fdc/fdc.c	11 Jan 2008 16:50:52 -0000	1.320
 +++ sys/dev/fdc/fdc.c	28 Oct 2008 17:00:01 -0000
 @@ -97,6 +97,8 @@ __FBSDID("$FreeBSD: src/sys/dev/fdc/fdc.
  				 * 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 */
  
 @@ -756,7 +758,7 @@ fdc_worker(struct fdc_data *fdc)
  	struct bio *bp;
  	int i, nsect;
  	int st0, st3, cyl, mfm, steptrac, cylinder, descyl, sec;
 -	int head;
 +	int flags, head;
  	static int need_recal;
  	struct fdc_readid *idp;
  	struct fd_formb *finfo;
 @@ -765,12 +767,15 @@ fdc_worker(struct fdc_data *fdc)
  	bp = fdc->bp;
  	fd = fdc->fd;
  	if (bp != NULL &&
 -		(fdc->retry >= retries || (fd->options & FDOPT_NORETRY))) {
 +	    (fdc->retry >= retries || (fdc->flags & FDC_NEEDS_RESET) ||
 +	    (fd->options & FDOPT_NORETRY))) {
  		if ((debugflags & 4))
  			printf("Too many retries (EIO)\n");
 -		mtx_lock(&fdc->fdc_mtx);
 -		fd->flags |= FD_EMPTY;
 -		mtx_unlock(&fdc->fdc_mtx);
 +		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));
  	}
  
 @@ -837,7 +842,8 @@ fdc_worker(struct fdc_data *fdc)
  
  	if (bp->bio_cmd & BIO_PROBE) {
  
 -		if (!(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
 +		if (!(device_get_flags(fd->dev) & FD_NO_CHLINE) &&
 +		    !(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
  			return (fdc_biodone(fdc, 0));
  
  		/*
 @@ -872,26 +878,25 @@ fdc_worker(struct fdc_data *fdc)
  		if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
  			return (1); /* XXX */
  		need_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 (debugflags & 0x40)
 -				printf("Got disk in probe\n");
 -			mtx_lock(&fdc->fdc_mtx);
 -			fd->flags &= ~FD_EMPTY;
 -			mtx_unlock(&fdc->fdc_mtx);
 +		flags = fd->flags;
 +		if (fdin_rd(fdc) & FDI_DCHG)
 +			flags |= FD_EMPTY;
 +		else {
  			retry_line = __LINE__;
 -			if(fdc_sense_drive(fdc, &st3) != 0)
 +			if (fdc_sense_drive(fdc, &st3) != 0)
  				return (1);
 -			mtx_lock(&fdc->fdc_mtx);
 -			if(st3 & NE7_ST3_WP)
 -				fd->flags |= FD_WP;
 +			if (st3 & NE7_ST3_WP)
 +				flags |= FD_WP;
  			else
 -				fd->flags &= ~FD_WP;
 +				flags &= ~FD_WP;
 +			flags &= ~FD_EMPTY;
 +		}
 +		if (debugflags & 0x40)
 +			printf("%s in probe\n", (flags & FD_EMPTY) ?
 +			    "Empty" : "Got disk");
 +		if (fd->flags != flags) {
 +			mtx_lock(&fdc->fdc_mtx);
 +			fd->flags = flags;
  			mtx_unlock(&fdc->fdc_mtx);
  		}
  		return (fdc_biodone(fdc, 0));
 @@ -1350,7 +1355,7 @@ fdautoselect(struct fd_data *fd)
  		if (debugflags & 0x40)
  			device_printf(fd->dev, "autoselection failed\n");
  		fdsettype(fd, fd_native_types[fd->type]);
 -		return (0);
 +		return (-1);
  	} else {
  		if (debugflags & 0x40) {
  			device_printf(fd->dev,
 @@ -1411,7 +1416,13 @@ fd_access(struct g_provider *pp, int r, 
  		if (fd->flags & FD_EMPTY)
  			return (ENXIO);
  		if (fd->flags & FD_NEWDISK) {
 -			fdautoselect(fd);
 +			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);
 
 --Boundary-00=_Ma0BJ/rsQrMDFhF--
State-Changed-From-To: analyzed->feedback 
State-Changed-By: jkim 
State-Changed-When: Tue Oct 28 17:33:13 UTC 2008 
State-Changed-Why:  
Feedback requested for a new patch. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116538 
State-Changed-From-To: feedback->closed 
State-Changed-By: jkim 
State-Changed-When: Mon Nov 17 19:23:55 UTC 2008 
State-Changed-Why:  
Feedback timeout and improved version is committed on HEAD. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116538 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116538: commit references a PR
Date: Wed, 21 Jan 2009 17:32:51 +0000 (UTC)

 Author: jkim
 Date: Wed Jan 21 17:32:26 2009
 New Revision: 187544
 URL: http://svn.freebsd.org/changeset/base/187544
 
 Log:
   MFC:	r184976
   
   - Revive fdc(4) per-device flag 0x10, which was removed in r1.284[1].
   - If the flag is set and auto-select fails, assume disk is not present.
   - Set disk empty flag only when the floppy controller reset is needed.
   It fixes regression introduced in r1.311, which prevented it from ignoring
   errors.  Now fdformat(1) and dd(1) with conv=noerror option can continue
   when read/write errors occur as they should.
   - Do not retry disk probing as it is extremely slow and pointless.
   - Move the disk probing code into a separate function.
   - Do not reset disk empty flag if write-protect check fails somehow.
   
   PR:		kern/116538[1]
 
 Modified:
   stable/7/sys/   (props changed)
   stable/7/sys/contrib/pf/   (props changed)
   stable/7/sys/dev/ath/ath_hal/   (props changed)
   stable/7/sys/dev/cxgb/   (props changed)
   stable/7/sys/dev/fdc/fdc.c
 
 Modified: stable/7/sys/dev/fdc/fdc.c
 ==============================================================================
 --- stable/7/sys/dev/fdc/fdc.c	Wed Jan 21 17:28:24 2009	(r187543)
 +++ stable/7/sys/dev/fdc/fdc.c	Wed Jan 21 17:32:26 2009	(r187544)
 @@ -97,6 +97,8 @@ __FBSDID("$FreeBSD$");
  				 * 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 */
  
 @@ -263,6 +265,7 @@ struct fd_data {
  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 *);
  
  SYSCTL_NODE(_debug, OID_AUTO, fdc, CTLFLAG_RW, 0, "fdc driver");
  
 @@ -768,9 +771,11 @@ fdc_worker(struct fdc_data *fdc)
  		(fdc->retry >= retries || (fd->options & FDOPT_NORETRY))) {
  		if ((debugflags & 4))
  			printf("Too many retries (EIO)\n");
 -		mtx_lock(&fdc->fdc_mtx);
 -		fd->flags |= FD_EMPTY;
 -		mtx_unlock(&fdc->fdc_mtx);
 +		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));
  	}
  
 @@ -836,65 +841,12 @@ fdc_worker(struct fdc_data *fdc)
  		fdctl_wr(fdc, fd->ft->trans);
  
  	if (bp->bio_cmd & BIO_PROBE) {
 -
 -		if (!(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY))
 +		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));
 -
 -		/*
 -		 * Try to find out if we have a disk in the drive
 -		 *
 -		 * 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);
 -		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);
 -
 -		/* Seek to track 1 */
 -		retry_line = __LINE__;
 -		if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, 1, 0))
 -			return (1);
 -		tsleep(fdc, PRIBIO, "fdseek", hz);
 -		retry_line = __LINE__;
 -		if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
 -			return (1); /* XXX */
 -		need_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 (debugflags & 0x40)
 -				printf("Got disk in probe\n");
 -			mtx_lock(&fdc->fdc_mtx);
 -			fd->flags &= ~FD_EMPTY;
 -			mtx_unlock(&fdc->fdc_mtx);
 -			retry_line = __LINE__;
 -			if(fdc_sense_drive(fdc, &st3) != 0)
 -				return (1);
 -			mtx_lock(&fdc->fdc_mtx);
 -			if(st3 & NE7_ST3_WP)
 -				fd->flags |= FD_WP;
 -			else
 -				fd->flags &= ~FD_WP;
 -			mtx_unlock(&fdc->fdc_mtx);
 -		}
 -		return (fdc_biodone(fdc, 0));
 +		return (1);
  	}
  
  	/*
 @@ -1238,6 +1190,71 @@ fd_enqueue(struct fd_data *fd, struct bi
  	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)
  {
 @@ -1350,7 +1367,7 @@ fdautoselect(struct fd_data *fd)
  		if (debugflags & 0x40)
  			device_printf(fd->dev, "autoselection failed\n");
  		fdsettype(fd, fd_native_types[fd->type]);
 -		return (0);
 +		return (-1);
  	} else {
  		if (debugflags & 0x40) {
  			device_printf(fd->dev,
 @@ -1411,7 +1428,13 @@ fd_access(struct g_provider *pp, int r, 
  		if (fd->flags & FD_EMPTY)
  			return (ENXIO);
  		if (fd->flags & FD_NEWDISK) {
 -			fdautoselect(fd);
 +			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);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
