summaryrefslogtreecommitdiff
path: root/sys/arch/mvme88k
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2008-01-05 00:34:08 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2008-01-05 00:34:08 +0000
commitf09a15b3e5bf201587fe4441b9655b355d8607d7 (patch)
tree5037149a48ebf57757b04cd391509d71a8d62f2b /sys/arch/mvme88k
parent5c12c4b53485ab5cdcdc63c4624f12dae6661a78 (diff)
For each channel, tell if it is single-ended or differential if we can know
this. Might help before someone sets his disks on fire. Especially with boards where not all channels are of the same type.
Diffstat (limited to 'sys/arch/mvme88k')
-rw-r--r--sys/arch/mvme88k/dev/vs.c143
-rw-r--r--sys/arch/mvme88k/dev/vsvar.h16
2 files changed, 101 insertions, 58 deletions
diff --git a/sys/arch/mvme88k/dev/vs.c b/sys/arch/mvme88k/dev/vs.c
index c47756d065e..cf5f592ee8e 100644
--- a/sys/arch/mvme88k/dev/vs.c
+++ b/sys/arch/mvme88k/dev/vs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vs.c,v 1.69 2008/01/03 22:32:42 miod Exp $ */
+/* $OpenBSD: vs.c,v 1.70 2008/01/05 00:34:07 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
@@ -98,6 +98,7 @@ void vs_chksense(struct scsi_xfer *);
void vs_dealloc_scatter_gather(M328_SG);
int vs_eintr(void *);
int vs_getcqe(struct vs_softc *, bus_addr_t *, bus_addr_t *);
+int vs_identify(struct vs_channel *, int);
int vs_initialize(struct vs_softc *);
int vs_intr(struct vs_softc *);
void vs_link_sg_element(sg_list_element_t *, vaddr_t, int);
@@ -148,6 +149,7 @@ void
vsattach(struct device *parent, struct device *self, void *args)
{
struct vs_softc *sc = (struct vs_softc *)self;
+ struct vs_channel *vc;
struct confargs *ca = args;
struct scsi_link *sc_link;
struct scsibus_attach_args saa;
@@ -197,42 +199,43 @@ vsattach(struct device *parent, struct device *self, void *args)
"%s_err", self->dv_xname);
vmeintr_establish(sc->sc_evec, &sc->sc_ih_e, sc->sc_intrname_e);
- printf("SCSI ID");
+ /*
+ * Attach all scsi units on us, watching for boot device
+ * (see device_register).
+ */
+ tmp = bootpart;
+ if (sc->sc_paddr != bootaddr)
+ bootpart = -1; /* invalid flag to device_register */
for (bus = 0; bus < 2; bus++) {
- if (sc->sc_id[bus] < 0)
+ vc = &sc->sc_channel[bus];
+ if (vc->vc_id < 0)
continue;
- sc_link = &sc->sc_link[bus];
+ sc_link = &vc->vc_link;
sc_link->adapter = &vs_scsiswitch;
- sc_link->adapter_buswidth = sc->sc_width[bus];
+ sc_link->adapter_buswidth = vc->vc_width;
sc_link->adapter_softc = sc;
- sc_link->adapter_target = sc->sc_id[bus];
+ sc_link->adapter_target = vc->vc_id;
sc_link->device = &vs_scsidev;
if (sc->sc_bid != JAGUAR)
- sc_link->luns = 1;
+ sc_link->luns = 1; /* not enough queues */
sc_link->openings = 1;
if (bus != 0)
sc_link->flags = SDEV_2NDBUS;
- printf("%c%d", bus == 0 ? ' ' : '/', sc->sc_id[bus]);
- }
-
- printf("\n");
-
- /*
- * Attach all scsi units on us, watching for boot device
- * (see device_register).
- */
- tmp = bootpart;
- if (sc->sc_paddr != bootaddr)
- bootpart = -1; /* invalid flag to device_register */
-
- for (bus = 0; bus < 2; bus++) {
- if (sc->sc_id[bus] < 0)
- continue;
+ printf("%s: channel %d, ", sc->sc_dev.dv_xname, bus);
+ switch (vc->vc_type) {
+ case VCT_SE:
+ printf("single-ended, ");
+ break;
+ case VCT_DIFFERENTIAL:
+ printf("differential, ");
+ break;
+ }
+ printf("SCSI ID %d\n", vc->vc_id);
- if (sc->sc_width[bus] == 0) {
+ if (vc->vc_width == 0) {
printf("%s: daughterboard disabled, "
"not enough on-board memory\n",
sc->sc_dev.dv_xname);
@@ -240,7 +243,7 @@ vsattach(struct device *parent, struct device *self, void *args)
}
bzero(&saa, sizeof(saa));
- saa.saa_sc_link = &sc->sc_link[bus];
+ saa.saa_sc_link = &vc->vc_link;
bootbus = bus;
config_found(self, &saa, scsiprint);
@@ -259,8 +262,8 @@ vs_print_addr(struct vs_softc *sc, struct scsi_xfer *xs)
sc_print_addr(xs->sc_link);
/* print bus number too if appropriate */
- if (sc->sc_width[1] >= 0)
- printf("(bus %d) ",
+ if (sc->sc_channel[1].vc_width >= 0)
+ printf("(channel %d) ",
!!(xs->sc_link->flags & SDEV_2NDBUS));
}
}
@@ -613,6 +616,41 @@ vs_getcqe(struct vs_softc *sc, bus_addr_t *cqep, bus_addr_t *iopbp)
}
int
+vs_identify(struct vs_channel *vc, int cid)
+{
+ vc->vc_width = 0;
+ vc->vc_type = VCT_UNKNOWN;
+
+ if (vc->vc_id < 0)
+ return (0);
+
+ switch (cid) {
+ case 0x00:
+ vc->vc_width = 8;
+ vc->vc_type = VCT_SE;
+ break;
+ case 0x01:
+ vc->vc_width = 8;
+ vc->vc_type = VCT_DIFFERENTIAL;
+ break;
+ case 0x02:
+ vc->vc_width = 16;
+ vc->vc_type = VCT_SE;
+ break;
+ case 0x03:
+ case 0x0e:
+ vc->vc_width = 16;
+ vc->vc_type = VCT_DIFFERENTIAL;
+ break;
+ default:
+ vc->vc_id = -1;
+ return (0);
+ }
+
+ return (vc->vc_width - 1);
+}
+
+int
vs_initialize(struct vs_softc *sc)
{
int i, msr, id;
@@ -652,39 +690,38 @@ vs_initialize(struct vs_softc *sc)
id = csb_read(1, CSB_EXTID);
switch (id) {
case 0x00:
- printf("Cougar, ");
+ printf("Cougar");
break;
case 0x02:
- printf("Cougar II, ");
+ printf("Cougar II");
break;
default:
- printf("unknown Cougar %02x, ", id);
+ printf("unknown Cougar version %02x", id);
break;
}
break;
}
/* initialize channels id */
- sc->sc_id[0] = csb_read(1, CSB_PID);
- sc->sc_id[1] = -1;
+ sc->sc_channel[0].vc_id = csb_read(1, CSB_PID);
+ sc->sc_channel[1].vc_id = -1;
switch (id = csb_read(1, CSB_DBID)) {
case DBID_SCSI2:
case DBID_SCSI:
-#if 0
- printf("daughter board, ");
-#endif
- sc->sc_id[1] = csb_read(1, CSB_SID);
+ sc->sc_channel[1].vc_id = csb_read(1, CSB_SID);
break;
case DBID_PRINTER:
- printf("printer port, ");
+ printf("with printer port");
break;
case DBID_NONE:
break;
default:
- printf("unknown daughterboard id %x, ", id);
+ printf("with unknown daughterboard id %x", id);
break;
}
+ printf("\n");
+
/*
* On cougar boards, find how many work queues we can use,
* and whether we are on wide or narrow buses.
@@ -715,14 +752,10 @@ vs_initialize(struct vs_softc *sc)
if (sc->sc_nwq > NUM_WQ)
sc->sc_nwq = NUM_WQ;
- sc->sc_width[0] = csb_read(1, CSB_PFECID) & 0x02 ? 16 : 8;
- targets = sc->sc_width[0] - 1;
- if (sc->sc_id[1] >= 0) {
- sc->sc_width[1] =
- csb_read(1, CSB_SFECID) & 0x02 ? 16 : 8;
- targets += sc->sc_width[1] - 1;
- } else
- sc->sc_width[1] = 0;
+ targets = vs_identify(&sc->sc_channel[0],
+ csb_read(1, CSB_PFECID));
+ targets += vs_identify(&sc->sc_channel[1],
+ csb_read(1, CSB_SFECID));
if (sc->sc_nwq > targets)
sc->sc_nwq = targets;
@@ -733,13 +766,13 @@ vs_initialize(struct vs_softc *sc)
* XXX This might work by moving everything off-board?
*/
if (sc->sc_nwq < targets)
- sc->sc_width[1] = 0;
+ sc->sc_channel[1].vc_width = 0;
}
break;
default:
case JAGUAR:
sc->sc_nwq = JAGUAR_MAX_WQ;
- sc->sc_width[0] = sc->sc_width[1] = 8;
+ sc->sc_channel[0].vc_width = sc->sc_channel[1].vc_width = 8;
break;
}
@@ -809,8 +842,8 @@ vs_initialize(struct vs_softc *sc)
mce_iopb_write(4, WQCF_CMDTO, 4); /* 1 second */
if (sc->sc_bid != JAGUAR)
mce_iopb_write(2, WQCF_UNIT,
- vs_unit_value(i > sc->sc_width[0],
- i - sc->sc_width[0], 0));
+ vs_unit_value(i > sc->sc_channel[0].vc_width,
+ i - sc->sc_channel[0].vc_width, 0));
vs_bzero(sh_MCE, CQE_SIZE);
mce_write(2, CQE_IOPB_ADDR, sh_MCE_IOPB);
@@ -842,14 +875,16 @@ vs_initialize(struct vs_softc *sc)
void
vs_resync(struct vs_softc *sc)
{
+ struct vs_channel *vc;
int bus, target;
for (bus = 0; bus < 2; bus++) {
- if (sc->sc_id[bus] < 0 || sc->sc_width[bus] == 0)
+ vc = &sc->sc_channel[bus];
+ if (vc->vc_id < 0 || vc->vc_width == 0)
break;
- for (target = 0; target < sc->sc_width[bus]; target++) {
- if (target == sc->sc_id[bus])
+ for (target = 0; target < vc->vc_width; target++) {
+ if (target == vc->vc_id)
continue;
/* Wait until we can use the command queue entry. */
@@ -1085,7 +1120,7 @@ vs_find_queue(struct scsi_link *sl, struct vs_softc *sc)
if (q == 0)
q = sl->adapter_target;
if (sl->flags & SDEV_2NDBUS)
- q += sc->sc_width[0] - 1; /* map to 8-14 or 16-30 */
+ q += sc->sc_channel[0].vc_width - 1; /* map to 8-14 or 16-30 */
if ((cb = &sc->sc_cb[q])->cb_xs == NULL)
return (cb);
diff --git a/sys/arch/mvme88k/dev/vsvar.h b/sys/arch/mvme88k/dev/vsvar.h
index 36d947f25fd..8c6b32f7bb2 100644
--- a/sys/arch/mvme88k/dev/vsvar.h
+++ b/sys/arch/mvme88k/dev/vsvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vsvar.h,v 1.19 2008/01/01 22:54:28 miod Exp $ */
+/* $OpenBSD: vsvar.h,v 1.20 2008/01/05 00:34:07 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
* Copyright (c) 1999 Steve Murphree, Jr.
@@ -90,6 +90,16 @@ struct vs_cb {
M328_SG cb_sg;
};
+struct vs_channel {
+ int vc_id; /* host id */
+ int vc_width; /* number of targets */
+ int vc_type; /* channel type */
+#define VCT_UNKNOWN 0
+#define VCT_SE 1
+#define VCT_DIFFERENTIAL 2
+ struct scsi_link vc_link;
+};
+
struct vs_softc {
struct device sc_dev;
int sc_bid; /* board id */
@@ -101,9 +111,7 @@ struct vs_softc {
int sc_ipl;
int sc_evec, sc_nvec;
u_int sc_nwq; /* number of work queues */
- int sc_id[2]; /* host id per bus */
- int sc_width[2]; /* number of targets per bus */
- struct scsi_link sc_link[2];
+ struct vs_channel sc_channel[2];
struct vs_cb sc_cb[1 + NUM_WQ];
};