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--