Source-Changes-HG archive

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

[src/thorpej_scsipi]: src/sys/dev/scsipi Deal a little more gracefully with t...



details:   https://anonhg.NetBSD.org/src/rev/9aceab0bd313
branches:  thorpej_scsipi
changeset: 477303:9aceab0bd313
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Tue Oct 26 23:08:05 1999 +0000

description:
Deal a little more gracefully with the fact that xfer mode parameters
are for the I_T Nexus, and make all xfer mode updates `async events'.

diffstat:

 sys/dev/scsipi/scsiconf.c    |  56 ++++----------------------
 sys/dev/scsipi/scsipi_base.c |  91 +++++++++++++++++++++++++++++++++++++++++--
 sys/dev/scsipi/scsipiconf.h  |  16 +++---
 3 files changed, 103 insertions(+), 60 deletions(-)

diffs (243 lines):

diff -r 596ed1998063 -r 9aceab0bd313 sys/dev/scsipi/scsiconf.c
--- a/sys/dev/scsipi/scsiconf.c Wed Oct 20 22:57:21 1999 +0000
+++ b/sys/dev/scsipi/scsiconf.c Tue Oct 26 23:08:05 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: scsiconf.c,v 1.130.2.2 1999/10/20 22:54:09 thorpej Exp $       */
+/*     $NetBSD: scsiconf.c,v 1.130.2.3 1999/10/26 23:08:05 thorpej Exp $       */
 
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -314,6 +314,13 @@
                                break;
                        /* otherwise something says we should look further */
                }
+               
+               /*
+                * Now that we've discovered all of the LUNs on this
+                * I_T Nexus, update the xfer mode for all of them
+                * that we know about.
+                */
+               scsipi_set_xfer_mode(chan, target, 1);
        }
        scsipi_adapter_delref(chan->chan_adapter);
        return (0);
@@ -612,7 +619,7 @@
        struct scsipi_periph *periph;
        struct scsipi_inquiry_data inqbuf;
        struct scsi_quirk_inquiry_pattern *finger;
-       int i, checkdtype, priority, docontinue, quirks, s;
+       int i, checkdtype, priority, docontinue, quirks;
        struct scsipibus_attach_args sa;
        struct cfdata *cf;
 
@@ -789,51 +796,6 @@
                 * XXX assign it in periph driver.
                 */
                (void) config_attach(&sc->sc_dev, cf, &sa, scsibusprint);
-
-               if (lun == 0) {
-                       /*
-                        * Issue a request to the adapter to negotiate the best
-                        * possible xfer mode given our capabilities.
-                        */
-                       s = splbio();
-                       scsipi_adapter_request(chan, ADAPTER_REQ_SET_XFER_MODE,
-                           periph);
-                       splx(s);
-
-                       /*
-                        * Issue a dummy command; some adapters can only really
-                        * do xfer mode negotiation when performing a command.
-                        */
-                       (void) scsipi_test_unit_ready(periph,
-                           XS_CTL_DISCOVERY | XS_CTL_IGNORE_ILLEGAL_REQUEST |
-                           XS_CTL_IGNORE_NOT_READY |
-                           XS_CTL_IGNORE_MEDIA_CHANGE);
-               
-                       /*
-                        * Now get the xfer mode settings.
-                        */
-                       s = splbio();
-                       scsipi_adapter_request(chan, ADAPTER_REQ_GET_XFER_MODE,
-                           periph);
-                       splx(s);
-               } else {
-                       /*
-                        * Not the first LUN; devices of this sort inherit
-                        * the xfer mode paramters of the I_T Nexus, masked
-                        * by their own capabilities.
-                        */
-                       struct scsipi_periph *itperiph =
-                           scsipi_lookup_periph(chan, target, 0);
-                       if (itperiph != NULL) {
-                               periph->periph_mode =
-                                   itperiph->periph_mode & periph->periph_cap;
-                               periph->periph_period = itperiph->periph_period;
-                               periph->periph_offset = itperiph->periph_offset;
-                               periph->periph_flags |=
-                                 itperiph->periph_flags & PERIPH_MODE_VALID;
-                       }
-               }
-               scsipi_print_xfer_mode(periph);
        } else {
                scsibusprint(&sa, sc->sc_dev.dv_xname);
                printf(" not configured\n");
diff -r 596ed1998063 -r 9aceab0bd313 sys/dev/scsipi/scsipi_base.c
--- a/sys/dev/scsipi/scsipi_base.c      Wed Oct 20 22:57:21 1999 +0000
+++ b/sys/dev/scsipi/scsipi_base.c      Tue Oct 26 23:08:05 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: scsipi_base.c,v 1.26.2.4 1999/10/20 22:50:47 thorpej Exp $     */
+/*     $NetBSD: scsipi_base.c,v 1.26.2.5 1999/10/26 23:08:06 thorpej Exp $     */
 
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -1757,15 +1757,96 @@
        struct scsipi_xfer_mode *xm;
 {
        struct scsipi_periph *periph;
-       int lun;
+       int lun, announce, mode, period, offset;
 
        for (lun = 0; lun < chan->chan_nluns; lun++) {
                periph = scsipi_lookup_periph(chan, xm->xm_target, lun);
                if (periph == NULL)
                        continue;
-               scsipi_adapter_request(chan, ADAPTER_REQ_GET_XFER_MODE, periph);
-               periph->periph_mode &= periph->periph_cap;
-               scsipi_print_xfer_mode(periph);
+               announce = 0;
+
+               /*
+                * Clamp the xfer mode down to this periph's capabilities.
+                */
+               mode = xm->xm_mode & periph->periph_cap;
+               if (mode & PERIPH_CAP_SYNC) {
+                       period = xm->xm_period;
+                       offset = xm->xm_offset;
+               } else {
+                       period = 0;
+                       offset = 0;
+               }
+
+               /*
+                * If we do not have a valid xfer mode yet, or the parameters
+                * are different, announce them.
+                */
+               if ((periph->periph_flags & PERIPH_MODE_VALID) == 0 ||
+                   periph->periph_mode != mode ||
+                   periph->periph_period != period ||
+                   periph->periph_offset != offset)
+                       announce = 1;
+
+               periph->periph_mode = mode;
+               periph->periph_period = period;
+               periph->periph_offset = offset;
+               periph->periph_flags |= PERIPH_MODE_VALID;
+
+               if (announce)
+                       scsipi_print_xfer_mode(periph);
+       }
+}
+
+/*
+ * scsipi_set_xfer_mode:
+ *
+ *     Set the xfer mode for the specified I_T Nexus.
+ */
+void
+scsipi_set_xfer_mode(chan, target, immed)
+       struct scsipi_channel *chan;
+       int target, immed;
+{
+       struct scsipi_xfer_mode xm;
+       struct scsipi_periph *itperiph;
+       int lun, s;
+
+       /*
+        * Go to the minimal xfer mode.
+        */
+       xm.xm_target = target;
+       xm.xm_mode = 0;
+       xm.xm_period = 0;                       /* ignored */
+       xm.xm_offset = 0;                       /* ignored */
+
+       /*
+        * Find the first LUN we know about on this I_T Nexus.
+        */
+       for (lun = 0; lun < chan->chan_nluns; lun++) {
+               itperiph = scsipi_lookup_periph(chan, target, lun);
+               if (itperiph != NULL)
+                       break;
+       }
+       if (itperiph != NULL)
+               xm.xm_mode = itperiph->periph_cap;
+
+       /*
+        * Now issue the request to the adapter.
+        */
+       s = splbio();
+       scsipi_adapter_request(chan, ADAPTER_REQ_SET_XFER_MODE, &xm);
+       splx(s);
+
+       /*
+        * If we want this to happen immediately, issue a dummy command,
+        * since most adapters can't really negotiate unless they're
+        * executing a job.
+        */
+       if (immed != 0 && itperiph != NULL) {
+               (void) scsipi_test_unit_ready(itperiph,
+                   XS_CTL_DISCOVERY | XS_CTL_IGNORE_ILLEGAL_REQUEST |
+                   XS_CTL_IGNORE_NOT_READY |
+                   XS_CTL_IGNORE_MEDIA_CHANGE);
        }
 }
 
diff -r 596ed1998063 -r 9aceab0bd313 sys/dev/scsipi/scsipiconf.h
--- a/sys/dev/scsipi/scsipiconf.h       Wed Oct 20 22:57:21 1999 +0000
+++ b/sys/dev/scsipi/scsipiconf.h       Tue Oct 26 23:08:05 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: scsipiconf.h,v 1.32.2.4 1999/10/20 22:52:18 thorpej Exp $      */
+/*     $NetBSD: scsipiconf.h,v 1.32.2.5 1999/10/26 23:08:06 thorpej Exp $      */
 
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -119,6 +119,9 @@
  */
 struct scsipi_xfer_mode {
        int     xm_target;              /* target, for I_T Nexus */
+       int     xm_mode;                /* PERIPH_CAP* bits */
+       int     xm_period;              /* sync period */
+       int     xm_offset;              /* sync offset */
 };
 
 
@@ -134,18 +137,14 @@
  *
  *     ADAPTER_REQ_GROW_RESOURCES      no argument
  *
- *     ADAPTER_REQ_SET_XFER_MODE       scsipi_periph * -- set the xfer
- *                                     mode based on the periph's
- *                                     capabilities
- *
- *     ADAPTER_REQ_GET_XFER_MODE       scsipi_periph * -- fill in the
- *                                     current mode in the periph
+ *     ADAPTER_REQ_SET_XFER_MODE       scsipi_xfer_mode * -- set the xfer
+ *                                     mode for the I_T Nexus according to
+ *                                     this
  */
 typedef enum {
        ADAPTER_REQ_RUN_XFER,           /* run a scsipi_xfer */
        ADAPTER_REQ_GROW_RESOURCES,     /* grow xfer execution resources */
        ADAPTER_REQ_SET_XFER_MODE,      /* set xfer mode */
-       ADAPTER_REQ_GET_XFER_MODE,      /* get xfer mode */
 } scsipi_adapter_req_t;
 
 
@@ -590,6 +589,7 @@
            int, struct proc *));
 
 void   scsipi_print_xfer_mode __P((struct scsipi_periph *));
+void   scsipi_set_xfer_mode __P((struct scsipi_channel *, int, int));
 
 void   scsipi_channel_init __P((struct scsipi_channel *));
 struct scsipi_periph *scsipi_lookup_periph __P((struct scsipi_channel *,



Home | Main Index | Thread Index | Old Index