Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3]: src/sys/dev/ic Pull up revision 1.224 (requested by bouyer in...



details:   https://anonhg.NetBSD.org/src/rev/f454b98502a2
branches:  netbsd-3
changeset: 576431:f454b98502a2
user:      tron <tron%NetBSD.org@localhost>
date:      Sat Jul 02 23:15:30 2005 +0000

description:
Pull up revision 1.224 (requested by bouyer in ticket #499):
In wdcprobe1(), wait 5s for the drive to deassert ready. In case of e.g.
pcmcia devices, the drive may still be doing its power-on reset.
XXX From the specs the delay could be up to 31s here, but we don't want to
    wait for 31s if we have a channel with no drives and pull-up resitors on
    the bus.
Based on patch submitted in kern/25659 by Steven M. Bellovin, part of fix for
kern/25659.

diffstat:

 sys/dev/ic/wdc.c |  49 +++++++++++++++++++++++++++++++------------------
 1 files changed, 31 insertions(+), 18 deletions(-)

diffs (90 lines):

diff -r f25011e3e657 -r f454b98502a2 sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c  Sat Jul 02 18:53:51 2005 +0000
+++ b/sys/dev/ic/wdc.c  Sat Jul 02 23:15:30 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdc.c,v 1.220.2.1 2005/06/22 18:38:33 tron Exp $ */
+/*     $NetBSD: wdc.c,v 1.220.2.2 2005/07/02 23:15:30 tron Exp $ */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.220.2.1 2005/06/22 18:38:33 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.220.2.2 2005/07/02 23:15:30 tron Exp $");
 
 #ifndef ATADEBUG
 #define ATADEBUG
@@ -119,6 +119,14 @@
 /* timeout for the control commands */
 #define WDC_CTRL_DELAY 10000 /* 10s, for the recall command */
 
+/*
+ * timeout when waiting for BSY to deassert when probing.
+ * set to 5s. From the standards this could be up to 31, but we can't
+ * wait that much at boot time, and 5s seems to be enouth.
+ */
+#define WDC_PROBE_WAIT 5
+
+
 #if NWD > 0
 extern const struct ata_bustype wdc_ata_bustype; /* in ata_wdc.c */
 #else
@@ -399,10 +407,12 @@
        struct atac_softc *atac = chp->ch_atac;
        struct wdc_softc *wdc = CHAN_TO_WDC(chp);
        struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
-       u_int8_t st0, st1, sc, sn, cl, ch;
+       u_int8_t st0 = 0, st1 = 0, sc, sn, cl, ch;
        u_int8_t ret_value = 0x03;
        u_int8_t drive;
        int s;
+       int wdc_probe_count =
+           poll ? (WDC_PROBE_WAIT / WDCDELAY) : (WDC_PROBE_WAIT * hz);
 
        /*
         * Sanity check to see if the wdc channel responds at all.
@@ -410,24 +420,27 @@
 
        s = splbio();
        if ((wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
+               while (wdc_probe_count-- > 0) {
+                       if (wdc->select)
+                               wdc->select(chp,0);
 
-               if (wdc->select)
-                       wdc->select(chp,0);
+                       bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh],
+                           0, WDSD_IBM);
+                       delay(10);      /* 400ns delay */
+                       st0 = bus_space_read_1(wdr->cmd_iot,
+                           wdr->cmd_iohs[wd_status], 0);
 
-               bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
-                   WDSD_IBM);
-               delay(10);      /* 400ns delay */
-               st0 = bus_space_read_1(wdr->cmd_iot,
-                   wdr->cmd_iohs[wd_status], 0);
+                       if (wdc->select)
+                               wdc->select(chp,1);
 
-               if (wdc->select)
-                       wdc->select(chp,1);
-
-               bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
-                   WDSD_IBM | 0x10);
-               delay(10);      /* 400ns delay */
-               st1 = bus_space_read_1(wdr->cmd_iot,
-                   wdr->cmd_iohs[wd_status], 0);
+                       bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh],
+                           0, WDSD_IBM | 0x10);
+                       delay(10);      /* 400ns delay */
+                       st1 = bus_space_read_1(wdr->cmd_iot,
+                           wdr->cmd_iohs[wd_status], 0);
+                       if ((st0 & WDCS_BSY) == 0)
+                               break;
+               }
 
                ATADEBUG_PRINT(("%s:%d: before reset, st0=0x%x, st1=0x%x\n",
                    atac->atac_dev.dv_xname,



Home | Main Index | Thread Index | Old Index