Subject: Re: i386 - Cannot boot from wd(Promise Ultra100) with infinite ``bogus inter'' msg
To: NISHIO Yasuhiro <nishio@hh.iij4u.or.jp>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: current-users
Date: 10/15/2003 22:50:06
--DKU6Jbt7q3WqK7+M
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Thu, Oct 16, 2003 at 01:26:44AM +0900, NISHIO Yasuhiro wrote:
> Bouyer san.
> Thank you for your reply.
> 
> > I think we can do without it
> 
> It's good news for me. ;-)
> 
> > Can you try the attached patch ?
> 
> I try it. And kernel loops on intr.

Sigh, we may have to block interrupts for the reset. Please try the
attached patch.

> 
> > It seems it starts looping when RST is asserted. Strange.
> 
> The machine has 5 PCI cards(VGA, fxp, wm, Promise IDE and cbb).  I
> think that I'll try to test with simple system configuration(VGA and
> Promise IDE only) on this weekend.
> 
> Is this meeninglee? 

It's worth a try, but I suspect it's more a disk bug.

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 24 ans d'experience feront toujours la difference
--

--DKU6Jbt7q3WqK7+M
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc.c,v
retrieving revision 1.143
diff -u -r1.143 wdc.c
--- wdc.c	15 Oct 2003 20:29:26 -0000	1.143
+++ wdc.c	15 Oct 2003 20:48:44 -0000
@@ -594,6 +594,7 @@
 	u_int8_t st0, st1, sc, sn, cl, ch;
 	u_int8_t ret_value = 0x03;
 	u_int8_t drive;
+	int s;
 
 	/*
 	 * Sanity check to see if the wdc channel responds at all.
@@ -690,6 +691,8 @@
 			return 0;
 	}
 
+	s=splbio();
+
 	if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
 		chp->wdc->select(chp,0);
 	/* assert SRST, wait for reset to complete */
@@ -707,6 +710,7 @@
 	WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
 	    chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
 	    ret_value), DEBUG_PROBE);
+	splx(s);
 
 	/* if reset failed, there's nothing here */
 	if (ret_value == 0)
@@ -1085,9 +1089,12 @@
 	int poll;
 {
 	int drv_mask1, drv_mask2;
+	int s;
 
 	if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
 		chp->wdc->select(chp,0);
+	if (poll != RESET_SLEEP)
+		s = splbio();
 	bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
 	    WDSD_IBM); /* master */
 	delay(10);	/* 400ns delay */
@@ -1103,6 +1110,8 @@
 	drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00;
 	drv_mask2 = __wdcwait_reset(chp, drv_mask1,
 	    (poll == RESET_SLEEP) ? 0 : 1);
+	if (poll != RESET_SLEEP)
+		splx(s);
 	if (drv_mask2 != drv_mask1) {
 		printf("%s channel %d: reset failed for",
 		    chp->wdc->sc_dev.dv_xname, chp->channel);

--DKU6Jbt7q3WqK7+M--