Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Fix probe code for IDE devices:



details:   https://anonhg.NetBSD.org/src/rev/67851b6b57ef
branches:  trunk
changeset: 471793:67851b6b57ef
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sun Apr 11 20:50:28 1999 +0000

description:
Fix probe code for IDE devices:
- Don't rely on ATA signature: some ide controllers seems to not transmit it
  properly (SIMIDE on arm32 machines). Instead, when we guess a drive is here
  after reset, just mark it as ATA and OLD is it's not ATAPI.
- at attach time, use IDENTIFY to eliminate ghost from the probe. If the
  drive had the old flag and IDENTIFY failed, issue a WDCC_RECAL command
  to detect a pre-ATA disk. If IDENTIFY succeded, remove the OLD flag,
  it's obviously not a pre-ATA disk.
- add a new controller flag, WDC_CAPABILITY_PREATA, used to shorcut parts
  of the probe (not necessary, but makes the probe/attach faster). This is
  only set by the ISA front-end, all other controllers supported can't have
  pre-ATA drives attached.
The mechanism used are more or less the same as before, they have just been
reordered. Should solve port-arm32/7324 (waiting for feedback).

diffstat:

 sys/dev/ic/wdc.c      |  105 ++++++++++++++++++++++---------------------------
 sys/dev/ic/wdcvar.h   |    3 +-
 sys/dev/isa/wdc_isa.c |    5 +-
 3 files changed, 52 insertions(+), 61 deletions(-)

diffs (193 lines):

diff -r c0e6fb89f7ef -r 67851b6b57ef sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c  Sun Apr 11 18:44:00 1999 +0000
+++ b/sys/dev/ic/wdc.c  Sun Apr 11 20:50:28 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdc.c,v 1.66 1999/04/01 21:46:29 bouyer Exp $ */
+/*     $NetBSD: wdc.c,v 1.67 1999/04/11 20:50:28 bouyer Exp $ */
 
 
 /*
@@ -231,9 +231,9 @@
 
        /*
         * Test presence of drives. First test register signatures looking for
-        * ATAPI devices , then rescan and try an ATA command, in case it's an
-        * old drive.
-        * Fill in drive_flags accordingly
+        * ATAPI devices. If it's not an ATAPI and reset said there may be
+        * something here assume it's ATA or OLD. Ghost will be killed later in
+        * attach routine.
         */
        for (drive = 0; drive < 2; drive++) {
                if ((ret_value & (0x01 << drive)) == 0)
@@ -253,63 +253,16 @@
                    chp->channel, drive, sc, sn, cl, ch), DEBUG_PROBE);
                /*
                 * sc is supposted to be 0x1 for ATAPI but at last one drive
-                * set it to 0x0.
+                * set it to 0x0 - or maybe it's the controller.
                 */
                if ((sc == 0x00 || sc == 0x01) && sn == 0x01 &&
                    cl == 0x14 && ch == 0xeb) {
                        chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
-               } else if (sc == 0x01 && sn == 0x01 &&
-                   cl == 0x00 && ch == 0x00) {
+               } else {
                        chp->ch_drive[drive].drive_flags |= DRIVE_ATA;
-               }
-       }
-       /*
-        * Maybe there's an old device, try to detect it if we didn't
-        * find a ATA or ATAPI device.
-        */
-       if ((chp->ch_drive[0].drive_flags & DRIVE) != 0 ||
-           (chp->ch_drive[1].drive_flags & DRIVE) != 0)
-               return (ret_value);     
-       for (drive = 0; drive < 2; drive++) {
-               if ((ret_value & (0x01 << drive)) == 0)
-                       continue;
-               bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
-                   WDSD_IBM | (drive << 4));
-               delay(10);
-               /*
-                * Test registers writability (Error register not writable,
-                * but cyllo is), then try an ATA command.
-                */
-               bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_error, 0x58);
-               bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo, 0xa5);
-               if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error) ==
-                   0x58 ||
-                   bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo) !=
-                   0xa5) {
-                       WDCDEBUG_PRINT(("%s:%d:%d: register writability "
-                           "failed\n",
-                           chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
-                           chp->channel, drive), DEBUG_PROBE);
-                       ret_value &= ~(0x01 << drive);
-                       continue;
-               }
-               if (wait_for_ready(chp, 10000) != 0) {
-                       WDCDEBUG_PRINT(("%s:%d:%d: not ready\n",
-                           chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
-                           chp->channel, drive), DEBUG_PROBE);
-                       ret_value &= ~(0x01 << drive);
-                       continue;
-               }
-               bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_command,
-                   WDCC_RECAL);
-               if (wait_for_ready(chp, 10000) == 0) {
-                       chp->ch_drive[drive].drive_flags |=
-                           DRIVE_OLD;
-               } else {
-                       WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
-                           chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
-                           chp->channel, drive), DEBUG_PROBE);
-                       ret_value &= ~(0x01 << drive);
+                       if (chp->wdc == NULL ||
+                           (chp->wdc->cap & WDC_CAPABILITY_PREATA) != 0)
+                               chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
                }
        }
        return (ret_value);     
@@ -351,12 +304,42 @@
                    (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
                    WDC_CAPABILITY_DATA32)
                        chp->ch_drive[i].drive_flags |= DRIVE_CAP32;
+               if ((chp->ch_drive[i].drive_flags & DRIVE) == 0)
+                       continue;
 
                /* Issue a IDENTIFY command, to try to detect slave ghost */
-               if (ata_get_params(&chp->ch_drive[i], AT_POLL, &params) !=
+               if (ata_get_params(&chp->ch_drive[i], AT_POLL, &params) ==
                    CMD_OK) {
+                       /* If IDENTIFY succeded, this is not an OLD ctrl */
+                       chp->ch_drive[0].drive_flags &= ~DRIVE_OLD;
+                       chp->ch_drive[1].drive_flags &= ~DRIVE_OLD;
+               } else {
                        chp->ch_drive[i].drive_flags &=
                            ~(DRIVE_ATA | DRIVE_ATAPI);
+                       WDCDEBUG_PRINT(("%s:%d:%d: IDENTIFY failed\n",
+                           chp->wdc->sc_dev.dv_xname,
+                           chp->channel, i), DEBUG_PROBE);
+                       if ((chp->ch_drive[i].drive_flags & DRIVE_OLD) == 0)
+                               continue;
+                       /* Pre-ATA drive ? */
+                       bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
+                           WDSD_IBM | (i << 4));
+                       delay(100);
+                       if (wait_for_ready(chp, 10000) != 0) {
+                               WDCDEBUG_PRINT(("%s:%d:%d: not ready\n",
+                                   chp->wdc->sc_dev.dv_xname,
+                                   chp->channel, i), DEBUG_PROBE);
+                               chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
+                               continue;
+                       }
+                       bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
+                           wd_command, WDCC_RECAL);
+                       if (wait_for_ready(chp, 10000) != 0) {
+                               WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
+                                   chp->wdc->sc_dev.dv_xname,
+                                   chp->channel, i), DEBUG_PROBE);
+                               chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
+                       }
                }
        }
        ctrl_flags = chp->wdc->sc_dev.dv_cfdata->cf_flags;
@@ -366,6 +349,11 @@
            chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
            DEBUG_PROBE);
 
+       /* If no drives, abort here */
+       if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 &&
+           (chp->ch_drive[1].drive_flags & DRIVE) == 0)
+               return;
+
        /*
         * Attach an ATAPI bus, if needed.
         */
@@ -391,7 +379,8 @@
        }
 
        for (i = 0; i < 2; i++) {
-               if ((chp->ch_drive[i].drive_flags & DRIVE_ATA) == 0) {
+               if ((chp->ch_drive[i].drive_flags &
+                   (DRIVE_ATA | DRIVE_OLD)) == 0) {
                        continue;
                }
                memset(&aa_link, 0, sizeof(struct ata_atapi_attach));
diff -r c0e6fb89f7ef -r 67851b6b57ef sys/dev/ic/wdcvar.h
--- a/sys/dev/ic/wdcvar.h       Sun Apr 11 18:44:00 1999 +0000
+++ b/sys/dev/ic/wdcvar.h       Sun Apr 11 20:50:28 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdcvar.h,v 1.16 1999/04/01 21:46:30 bouyer Exp $       */
+/*     $NetBSD: wdcvar.h,v 1.17 1999/04/11 20:50:29 bouyer Exp $       */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -90,6 +90,7 @@
 #define        WDC_CAPABILITY_ATA_NOSTREAM 0x0040 /* Don't use stream funcs on ATA */
 #define        WDC_CAPABILITY_ATAPI_NOSTREAM 0x0080 /* Don't use stream f on ATAPI */
 #define WDC_CAPABILITY_NO_EXTRA_RESETS 0x0100 /* only reset once */
+#define WDC_CAPABILITY_PREATA 0x0200 /* ctrl can be a pre-ata one */
        u_int8_t      PIO_cap; /* highest PIO mode supported */
        u_int8_t      DMA_cap; /* highest DMA mode supported */
        u_int8_t      UDMA_cap; /* highest UDMA mode supported */
diff -r c0e6fb89f7ef -r 67851b6b57ef sys/dev/isa/wdc_isa.c
--- a/sys/dev/isa/wdc_isa.c     Sun Apr 11 18:44:00 1999 +0000
+++ b/sys/dev/isa/wdc_isa.c     Sun Apr 11 20:50:28 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdc_isa.c,v 1.13 1999/02/22 03:24:33 mycroft Exp $ */
+/*     $NetBSD: wdc_isa.c,v 1.14 1999/04/11 20:50:29 bouyer Exp $ */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -150,7 +150,8 @@
                sc->sc_wdcdev.dma_finish = wdc_isa_dma_finish;
                wdc_isa_dma_setup(sc);
        }
-       sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32;
+       sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
+           WDC_CAPABILITY_PREATA;
        sc->sc_wdcdev.PIO_cap = 0;
        sc->wdc_chanptr = &sc->wdc_channel;
        sc->sc_wdcdev.channels = &sc->wdc_chanptr;



Home | Main Index | Thread Index | Old Index