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