Source-Changes-HG archive

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

[src/netbsd-1-5]: src/sys/dev/ic Pull up rev 1.38 (approved by thorpej):



details:   https://anonhg.NetBSD.org/src/rev/2859bc76da92
branches:  netbsd-1-5
changeset: 489662:2859bc76da92
user:      simonb <simonb%NetBSD.org@localhost>
date:      Wed Oct 04 04:12:12 2000 +0000

description:
Pull up rev 1.38 (approved by thorpej):
 Revert rev 1.31 of bha.c (and associtated changes in the headers and
 config glue files).

 Fixes PR kern/9841.  Tested by Tracy J. Di Marco White with a bt948
 and 6 disks.

diffstat:

 sys/dev/ic/bha.c |  2580 +++++++++++++++++++++++------------------------------
 1 files changed, 1107 insertions(+), 1473 deletions(-)

diffs (truncated from 2721 to 300 lines):

diff -r 392736a45628 -r 2859bc76da92 sys/dev/ic/bha.c
--- a/sys/dev/ic/bha.c  Wed Oct 04 02:38:55 2000 +0000
+++ b/sys/dev/ic/bha.c  Wed Oct 04 04:12:12 2000 +0000
@@ -1,7 +1,15 @@
-/*     $NetBSD: bha.c,v 1.36 2000/03/30 12:45:30 augustss Exp $        */
+/*     $NetBSD: bha.c,v 1.36.4.1 2000/10/04 04:12:12 simonb Exp $      */
+
+#include "opt_ddb.h"
+#undef BHADIAG
+#ifdef DDB
+#define        integrate
+#else
+#define        integrate       static inline
+#endif
 
 /*-
- * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -52,8 +60,6 @@
  * functioning of this software in any circumstances.
  */
 
-#include "opt_ddb.h"
-
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -89,30 +95,24 @@
 int     bha_debug = 0;
 #endif /* BHADEBUG */
 
-int    bha_cmd __P((bus_space_tag_t, bus_space_handle_t, struct bha_softc *,
-           int, u_char *, int, u_char *));
-
-int    bha_scsi_cmd __P((struct scsipi_xfer *));
-void   bha_minphys __P((struct buf *));
-
-void   bha_done __P((struct bha_softc *, struct bha_ccb *));
-int    bha_poll __P((struct bha_softc *, struct scsipi_xfer *, int));
-void   bha_timeout __P((void *arg));
-
-int    bha_init __P((struct bha_softc *));
-
-int    bha_create_mailbox __P((struct bha_softc *));
-void   bha_collect_mbo __P((struct bha_softc *));
-
-void   bha_queue_ccb __P((struct bha_softc *, struct bha_ccb *));
-void   bha_start_ccbs __P((struct bha_softc *));
-void   bha_finish_ccbs __P((struct bha_softc *));
-
+int bha_cmd __P((bus_space_tag_t, bus_space_handle_t, struct bha_softc *,
+                int, u_char *, int, u_char *));
+integrate void bha_finish_ccbs __P((struct bha_softc *));
+integrate void bha_reset_ccb __P((struct bha_softc *, struct bha_ccb *));
+void bha_free_ccb __P((struct bha_softc *, struct bha_ccb *));
+integrate int bha_init_ccb __P((struct bha_softc *, struct bha_ccb *));
+struct bha_ccb *bha_get_ccb __P((struct bha_softc *, int));
 struct bha_ccb *bha_ccb_phys_kv __P((struct bha_softc *, bus_addr_t));
-void   bha_create_ccbs __P((struct bha_softc *, int));
-int    bha_init_ccb __P((struct bha_softc *, struct bha_ccb *));
-struct bha_ccb *bha_get_ccb __P((struct bha_softc *, int));
-void   bha_free_ccb __P((struct bha_softc *, struct bha_ccb *));
+void bha_queue_ccb __P((struct bha_softc *, struct bha_ccb *));
+void bha_collect_mbo __P((struct bha_softc *));
+void bha_start_ccbs __P((struct bha_softc *));
+void bha_done __P((struct bha_softc *, struct bha_ccb *));
+int bha_init __P((struct bha_softc *));
+void bhaminphys __P((struct buf *));
+int bha_scsi_cmd __P((struct scsipi_xfer *));
+int bha_poll __P((struct bha_softc *, struct scsipi_xfer *, int));
+void bha_timeout __P((void *arg));
+int bha_create_ccbs __P((struct bha_softc *, struct bha_ccb *, int));
 
 /* the below structure is so we have a default dev struct for out link struct */
 struct scsipi_device bha_dev = {
@@ -126,108 +126,297 @@
 #define        BHA_ABORT_TIMEOUT       2000    /* time to wait for abort (mSec) */
 
 /*
- * Number of CCBs in an allocation group; must be computed at run-time.
+ * bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
+ *
+ * Activate Adapter command
+ *    icnt:   number of args (outbound bytes including opcode)
+ *    ibuf:   argument buffer
+ *    ocnt:   number of expected returned bytes
+ *    obuf:   result buffer
+ *    wait:   number of seconds to wait for response
+ *
+ * Performs an adapter command through the ports.  Not to be confused with a
+ * scsi command, which is read in via the dma; one of the adapter commands
+ * tells it to read in a scsi command.
  */
-int    bha_ccbs_per_group;
+int
+bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
+       bus_space_tag_t iot;
+       bus_space_handle_t ioh;
+       struct bha_softc *sc;
+       int icnt, ocnt;
+       u_char *ibuf, *obuf;
+{
+       const char *name;
+       int i;
+       int wait;
+       u_char sts;
+       u_char opcode = ibuf[0];
 
-__inline struct bha_mbx_out *bha_nextmbo __P((struct bha_softc *,
-       struct bha_mbx_out *));
-__inline struct bha_mbx_in *bha_nextmbi __P((struct bha_softc *,
-       struct bha_mbx_in *));
+       if (sc != NULL)
+               name = sc->sc_dev.dv_xname;
+       else
+               name = "(bha probe)";
 
-__inline struct bha_mbx_out *
-bha_nextmbo(sc, mbo)
-       struct bha_softc *sc;
-       struct bha_mbx_out *mbo;
-{
+       /*
+        * Calculate a reasonable timeout for the command.
+        */
+       switch (opcode) {
+       case BHA_INQUIRE_DEVICES:
+       case BHA_INQUIRE_DEVICES_2:
+               wait = 90 * 20000;
+               break;
+       default:
+               wait = 1 * 20000;
+               break;
+       }
 
-       if (mbo == &sc->sc_mbo[sc->sc_mbox_count - 1])
-               return (&sc->sc_mbo[0]);
-       return (mbo + 1);
-}
+       /*
+        * Wait for the adapter to go idle, unless it's one of
+        * the commands which don't need this
+        */
+       if (opcode != BHA_MBO_INTR_EN) {
+               for (i = 20000; i; i--) {       /* 1 sec? */
+                       sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
+                       if (sts & BHA_STAT_IDLE)
+                               break;
+                       delay(50);
+               }
+               if (!i) {
+                       printf("%s: bha_cmd, host not idle(0x%x)\n",
+                           name, sts);
+                       return (1);
+               }
+       }
+       /*
+        * Now that it is idle, if we expect output, preflush the
+        * queue feeding to us.
+        */
+       if (ocnt) {
+               while ((bus_space_read_1(iot, ioh, BHA_STAT_PORT)) &
+                   BHA_STAT_DF)
+                       bus_space_read_1(iot, ioh, BHA_DATA_PORT);
+       }
+       /*
+        * Output the command and the number of arguments given
+        * for each byte, first check the port is empty.
+        */
+       while (icnt--) {
+               for (i = wait; i; i--) {
+                       sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
+                       if (!(sts & BHA_STAT_CDF))
+                               break;
+                       delay(50);
+               }
+               if (!i) {
+                       if (opcode != BHA_INQUIRE_REVISION)
+                               printf("%s: bha_cmd, cmd/data port full\n",
+                                   name);
+                       goto bad;
+               }
+               bus_space_write_1(iot, ioh, BHA_CMD_PORT, *ibuf++);
+       }
+       /*
+        * If we expect input, loop that many times, each time,
+        * looking for the data register to have valid data
+        */
+       while (ocnt--) {
+               for (i = wait; i; i--) {
+                       sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
+                       if (sts & BHA_STAT_DF)
+                               break;
+                       delay(50);
+               }
+               if (!i) {
+                       if (opcode != BHA_INQUIRE_REVISION)
+                               printf("%s: bha_cmd, cmd/data port empty %d\n",
+                                   name, ocnt);
+                       goto bad;
+               }
+               *obuf++ = bus_space_read_1(iot, ioh, BHA_DATA_PORT);
+       }
+       /*
+        * Wait for the board to report a finished instruction.
+        * We may get an extra interrupt for the HACC signal, but this is
+        * unimportant.
+        */
+       if (opcode != BHA_MBO_INTR_EN && opcode != BHA_MODIFY_IOPORT) {
+               for (i = 20000; i; i--) {       /* 1 sec? */
+                       sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
+                       /* XXX Need to save this in the interrupt handler? */
+                       if (sts & BHA_INTR_HACC)
+                               break;
+                       delay(50);
+               }
+               if (!i) {
+                       printf("%s: bha_cmd, host not finished(0x%x)\n",
+                           name, sts);
+                       return (1);
+               }
+       }
+       bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
+       return (0);
 
-__inline struct bha_mbx_in *
-bha_nextmbi(sc, mbi)
-       struct bha_softc *sc;
-       struct bha_mbx_in *mbi;
-{
-
-       if (mbi == &sc->sc_mbi[sc->sc_mbox_count - 1])
-               return (&sc->sc_mbi[0]);
-       return (mbi + 1);
+bad:
+       bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_SRST);
+       return (1);
 }
 
 /*
- * bha_attach:
- *
- *     Finish attaching a Buslogic controller, and configure children.
+ * Attach all the sub-devices we can find
  */
 void
 bha_attach(sc, bpd)
        struct bha_softc *sc;
        struct bha_probe_data *bpd;
 {
-       int initial_ccbs;
-
-       /*
-        * Initialize the number of CCBs per group.
-        */
-       if (bha_ccbs_per_group == 0)
-               bha_ccbs_per_group = BHA_CCBS_PER_GROUP;
-
-       initial_ccbs = bha_info(sc);
-       if (initial_ccbs == 0) {
-               printf("%s: unable to get adapter info\n",
-                   sc->sc_dev.dv_xname);
-               return;
-       }
 
        /*
         * Fill in the adapter.
         */
        sc->sc_adapter.scsipi_cmd = bha_scsi_cmd;
-       sc->sc_adapter.scsipi_minphys = bha_minphys;
+       sc->sc_adapter.scsipi_minphys = bhaminphys;
 
        /*
         * fill in the prototype scsipi_link.
         */
        sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
        sc->sc_link.adapter_softc = sc;
-       sc->sc_link.scsipi_scsi.adapter_target = sc->sc_scsi_id;
+       sc->sc_link.scsipi_scsi.adapter_target = bpd->sc_scsi_dev;
        sc->sc_link.adapter = &sc->sc_adapter;
        sc->sc_link.device = &bha_dev;
        sc->sc_link.openings = 4;
-       sc->sc_link.scsipi_scsi.max_target =
-           (sc->sc_flags & BHAF_WIDE) ? 15 : 7;
-       sc->sc_link.scsipi_scsi.max_lun =
-           (sc->sc_flags & BHAF_WIDE_LUN) ? 31 : 7;
+       sc->sc_link.scsipi_scsi.max_target = bpd->sc_iswide ? 15 : 7;
+       sc->sc_link.scsipi_scsi.max_lun = 7;
        sc->sc_link.type = BUS_SCSI;
 
        TAILQ_INIT(&sc->sc_free_ccb);
        TAILQ_INIT(&sc->sc_waiting_ccb);
-       TAILQ_INIT(&sc->sc_allocating_ccbs);
        TAILQ_INIT(&sc->sc_queue);
 
-       if (bha_create_mailbox(sc) != 0)
+       bha_inquire_setup_information(sc);



Home | Main Index | Thread Index | Old Index