Subject: port-sun3/2145: [dM] ufsboot doesn't retry PROM calls
To: None <gnats-bugs@NetBSD.ORG>
From: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
List: netbsd-bugs
Date: 02/28/1996 06:14:39
>Number:         2145
>Category:       port-sun3
>Synopsis:       [dM] ufsboot doesn't retry PROM calls
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Feb 28 06:35:01 1996
>Last-Modified:
>Originator:     der Mouse
>Organization:
Dis-
>Release:        -current sup of Feb 27 08:30
>Environment:
	Sun-3/110, si scsi, Seagate ST15230N disk
>Description:
	Sometimes, while ufsboot is loading the kernel, the PROM disk
	driver will flake out and hang for a long time - 15 seconds? -
	with the disk busy light lit; then it will report a status
	message of FFFFFFFF and return failure to ufsboot.  ufsboot
	naturally enough gets upset over this, even though retrying the
	call does in fact work.
>How-To-Repeat:
	Reboot my Sun-3/110 repeatedly. :-(
>Fix:
	I just made disk_strategy(), in sun3/stand/libsa/dev_disk.c,
	retry calls that fail, on the assumption that any _real_
	failure would be hard.

--- OLD/libsa/dev_disk.c	Thu Jan  1 00:00:00 1970
+++ NEW/libsa/dev_disk.c	Thu Jan  1 00:00:00 1970
@@ -49,6 +49,8 @@
 #include "dvma.h"
 #include "promdev.h"
 
+#define RETRY_COUNT 5
+
 struct saioreq disk_ioreq;
 
 int
@@ -108,7 +110,7 @@
 	struct saioreq *si;
 	struct boottab *ops;
 	char *dmabuf;
-	int	si_flag, xcnt;
+	int	si_flag, xcnt, retry;
 
 	si = devdata;
 	ops = si->si_boottab;
@@ -117,15 +119,16 @@
 	printf("disk_strategy: size=%d dblk=%d\n", size, dblk);
 #endif
 
-	dmabuf = dvma_mapin(buf, size);
-	
-	si->si_bn = dblk;
-	si->si_ma = dmabuf;
-	si->si_cc =	size;
-
-	si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
-	xcnt = (*ops->b_strategy)(si, si_flag);
-	dvma_mapout(dmabuf, size);
+	for (retry=0; retry<RETRY_COUNT; retry++) {
+		dmabuf = dvma_mapin(buf, size);
+		si->si_bn = dblk;
+		si->si_ma = dmabuf;
+		si->si_cc = size;
+		si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
+		xcnt = (*ops->b_strategy)(si, si_flag);
+		dvma_mapout(dmabuf, size);
+		if (xcnt > 0) break;
+	}
 
 #ifdef DEBUG_PROM
 	printf("disk_strategy: xcnt = %x\n", xcnt);
@@ -143,4 +146,3 @@
 {
 	return EIO;
 }
-

					der Mouse

			    mouse@collatz.mcrcim.mcgill.edu
>Audit-Trail:
>Unformatted: