Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/mscp Adjust MSCP attach routines. The current code w...



details:   https://anonhg.NetBSD.org/src/rev/797e2a1fc0a0
branches:  trunk
changeset: 780070:797e2a1fc0a0
user:      abs <abs%NetBSD.org@localhost>
date:      Tue Jul 10 22:30:23 2012 +0000

description:
Adjust MSCP attach routines. The current code worked fine on simh-vax, but
unfortunately failed on at least one 'real' SCSI MSCP adaptor.
In the updated code mscp_attach() still iterates over each unit on a bus,
but mscp_dorsp() now detects if we have reached the last unit and does not
return a bogus additional unit. It also loses a few gotos and handles
noncontiguous unit numbers better.

diffstat:

 sys/dev/mscp/mscp_subr.c |  170 ++++++++++++++++++++++++----------------------
 1 files changed, 88 insertions(+), 82 deletions(-)

diffs (217 lines):

diff -r 7d25d1283530 -r 797e2a1fc0a0 sys/dev/mscp/mscp_subr.c
--- a/sys/dev/mscp/mscp_subr.c  Tue Jul 10 22:30:22 2012 +0000
+++ b/sys/dev/mscp/mscp_subr.c  Tue Jul 10 22:30:23 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mscp_subr.c,v 1.42 2012/06/22 20:42:24 abs Exp $       */
+/*     $NetBSD: mscp_subr.c,v 1.43 2012/07/10 22:30:23 abs Exp $       */
 /*
  * Copyright (c) 1988 Regents of the University of California.
  * All rights reserved.
@@ -75,7 +75,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mscp_subr.c,v 1.42 2012/06/22 20:42:24 abs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mscp_subr.c,v 1.43 2012/07/10 22:30:23 abs Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -112,7 +112,8 @@
 #define        WRITE_IP(x)     bus_space_write_2(mi->mi_iot, mi->mi_iph, 0, (x))
 #define        WRITE_SW(x)     bus_space_write_2(mi->mi_iot, mi->mi_swh, 0, (x))
 
-struct mscp slavereply;
+struct mscp mscp_cold_reply;
+int         mscp_cold_unit;
 
 #define NITEMS         4
 
@@ -178,7 +179,7 @@
        struct mscp *mp2;
        volatile struct mscp *mp;
        volatile int i;
-       int     timeout, error, next = 0;
+       int     timeout, error, unit;
 
        mi->mi_mc = ma->ma_mc;
        mi->mi_me = NULL;
@@ -263,96 +264,101 @@
         * Go out and search for sub-units on this MSCP bus,
         * and call config_found for each found.
         */
-findunit:
-       mp = mscp_getcp(mi, MSCP_DONTWAIT);
-       if (mp == NULL)
-               panic("mscpattach: no packets");
-       mp->mscp_opcode = M_OP_GETUNITST;
-       mp->mscp_unit = next;
-       mp->mscp_modifier = M_GUM_NEXTUNIT;
-       *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
-       slavereply.mscp_opcode = 0;
+       for (unit = 0; unit <= MSCP_MAX_UNIT; ++unit) {
+               mp = mscp_getcp(mi, MSCP_DONTWAIT);
+               if (mp == NULL)
+                       panic("mscpattach: no packets");
+               mp->mscp_opcode = M_OP_GETUNITST;
+               mp->mscp_unit = unit;
+               mp->mscp_modifier = M_GUM_NEXTUNIT;
+               *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+               mscp_cold_reply.mscp_opcode = 0;
+               mscp_cold_unit = mp->mscp_unit;
+
+               i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
+               mp = &mscp_cold_reply;
+               timeout = 1000;
 
-       i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
-       mp = &slavereply;
-       timeout = 1000;
-       while (timeout-- > 0) {
-               DELAY(10000);
-               if (mp->mscp_opcode)
-                       goto gotit;
-       }
-       printf("%s: no response to Get Unit Status request\n",
-           device_xname(&mi->mi_dev));
-       return;
+               while (!mp->mscp_opcode) {
+                       if ( --timeout == 0) {
+                               printf("%s: no Get Unit Status response\n",
+                                   device_xname(&mi->mi_dev));
+                               return;
+                       }
+                       DELAY(10000);
+               }
+
+               /*
+                * Got a slave response.  If the unit is there, use it.
+                */
 
-gotit: /*
-        * Got a slave response.  If the unit is there, use it.
-        */
-       switch (mp->mscp_status & M_ST_MASK) {
+               /*
+                * If we get a lower number, we have circulated around all
+                * devices and are finished, otherwise try to find next unit.
+                */
+               if (mp->mscp_unit < unit)
+                       return;
+               /*
+                * If a higher number, use it to skip non-present devices
+                */
+               if (mp->mscp_unit > unit)
+                       unit = mp->mscp_unit;
+
+               switch (mp->mscp_status & M_ST_MASK) {
 
-       case M_ST_SUCCESS:      /* worked */
-       case M_ST_AVAILABLE:    /* found another drive */
-               break;          /* use it */
+               case M_ST_SUCCESS:      /* worked */
+               case M_ST_AVAILABLE:    /* found another drive */
+                       break;          /* use it */
 
-       case M_ST_OFFLINE:
-               /*
-                * Figure out why it is off line.  It may be because
-                * it is nonexistent, or because it is spun down, or
-                * for some other reason.
-                */
-               switch (mp->mscp_status & ~M_ST_MASK) {
-
-               case M_OFFLINE_UNKNOWN:
+               case M_ST_OFFLINE:
                        /*
-                        * No such drive, and there are none with
-                        * higher unit numbers either, if we are
-                        * using M_GUM_NEXTUNIT.
+                        * Figure out why it is off line.  It may be because
+                        * it is nonexistent, or because it is spun down, or
+                        * for some other reason.
                         */
-                       mi->mi_ierr = 3;
-                       return;
+                       switch (mp->mscp_status & ~M_ST_MASK) {
+
+                       case M_OFFLINE_UNKNOWN:
+                               /*
+                                * No such drive, and there are none with
+                                * higher unit numbers either, if we are
+                                * using M_GUM_NEXTUNIT.
+                                */
+                               mi->mi_ierr = 3;
+                               break; /* return */
 
-               case M_OFFLINE_UNMOUNTED:
-                       /*
-                        * The drive is not spun up.  Use it anyway.
-                        *
-                        * N.B.: this seems to be a common occurrance
-                        * after a power failure.  The first attempt
-                        * to bring it on line seems to spin it up
-                        * (and thus takes several minutes).  Perhaps
-                        * we should note here that the on-line may
-                        * take longer than usual.
-                        */
+                       case M_OFFLINE_UNMOUNTED:
+                               /*
+                                * The drive is not spun up.  Use it anyway.
+                                *
+                                * N.B.: this seems to be a common occurrance
+                                * after a power failure.  The first attempt
+                                * to bring it on line seems to spin it up
+                                * (and thus takes several minutes).  Perhaps
+                                * we should note here that the on-line may
+                                * take longer than usual.
+                                */
+                               break;
+
+                       default:
+                               /*
+                                * In service, or something else unusable.
+                                */
+                               printf("%s: unit %d off line: ",
+                                   device_xname(&mi->mi_dev), mp->mscp_unit);
+                               mp2 = __UNVOLATILE(mp);
+                               mscp_printevent(mp2);
+                               break;
+                       }
                        break;
 
                default:
-                       /*
-                        * In service, or something else equally unusable.
-                        */
-                       printf("%s: unit %d off line: ", device_xname(&mi->mi_dev),
-                               mp->mscp_unit);
-                       mp2 = __UNVOLATILE(mp);
-                       mscp_printevent(mp2);
-                       next++;
-                       goto findunit;
+                       aprint_error_dev(&mi->mi_dev,
+                           "unable to get unit status: ");
+                       mscp_printevent(__UNVOLATILE(mp));
+                       return;
                }
-               break;
-
-       default:
-               aprint_error_dev(&mi->mi_dev, "unable to get unit status: ");
-               mscp_printevent(__UNVOLATILE(mp));
-               return;
        }
-
-       /*
-        * If we get a lower number, we have circulated around all
-        * devices and are finished, otherwise try to find next unit.
-        * We shouldn't ever get this, it's a workaround.
-        */
-       if (mp->mscp_unit < next)
-               return;
-
-       next = mp->mscp_unit + 1;
-       goto findunit;
 }
 
 



Home | Main Index | Thread Index | Old Index