diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mvme88k/dev/vs.c | 121 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vsreg.h | 6 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vsvar.h | 6 |
3 files changed, 92 insertions, 41 deletions
diff --git a/sys/arch/mvme88k/dev/vs.c b/sys/arch/mvme88k/dev/vs.c index bac621c582b..053cbd725a7 100644 --- a/sys/arch/mvme88k/dev/vs.c +++ b/sys/arch/mvme88k/dev/vs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vs.c,v 1.48 2004/07/20 20:28:54 miod Exp $ */ +/* $OpenBSD: vs.c,v 1.49 2004/07/20 20:32:02 miod Exp $ */ /* * Copyright (c) 2004, Miodrag Vallat. @@ -107,12 +107,12 @@ void vs_link_sg_element(sg_list_element_t *, vaddr_t, int); void vs_link_sg_list(sg_list_element_t *, vaddr_t, int); int vs_nintr(void *); int vs_poll(struct vs_softc *, struct scsi_xfer *); -void vs_reset(struct vs_softc *); +int vs_queue_number(struct scsi_link *, struct vs_softc *); +void vs_reset(struct vs_softc *, int); void vs_resync(struct vs_softc *); void vs_scsidone(struct vs_softc *, struct scsi_xfer *, int); static __inline__ void vs_clear_return_info(struct vs_softc *); -static __inline__ int vs_queue_number(int, int); static __inline__ paddr_t kvtop(vaddr_t); int @@ -136,7 +136,8 @@ vsattach(struct device *parent, struct device *self, void *args) { struct vs_softc *sc = (struct vs_softc *)self; struct confargs *ca = args; - int evec; + struct scsi_link *sc_link; + int evec, bus; int tmp; /* get the next available vector for the error interrupt */ @@ -166,13 +167,6 @@ vsattach(struct device *parent, struct device *self, void *args) if (vs_initialize(sc)) return; - sc->sc_link.adapter_softc = sc; - sc->sc_link.adapter_target = sc->sc_pid; - sc->sc_link.adapter = &vs_scsiswitch; - sc->sc_link.device = &vs_scsidev; - sc->sc_link.luns = 1; - sc->sc_link.openings = NUM_IOPB / 8; - sc->sc_ih_n.ih_fn = vs_nintr; sc->sc_ih_n.ih_arg = sc; sc->sc_ih_n.ih_wantframe = 0; @@ -193,14 +187,43 @@ vsattach(struct device *parent, struct device *self, void *args) evcount_attach(&sc->sc_intrcnt_e, sc->sc_intrname_e, (void *)&sc->sc_ih_e.ih_ipl, &evcount_intr); + printf("SCSI ID"); + + for (bus = 0; bus < 2; bus++) { + if (sc->sc_id[bus] < 0) + continue; + + sc_link = &sc->sc_link[bus]; + sc_link->adapter = &vs_scsiswitch; + sc_link->adapter_buswidth = 8; + sc_link->adapter_softc = sc; + sc_link->adapter_target = sc->sc_id[bus]; + sc_link->device = &vs_scsidev; + sc_link->luns = 1; + sc_link->openings = NUM_IOPB / 8; + 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 + * Attach all scsi units on us, watching for boot device * (see dk_establish). */ tmp = bootpart; if (sc->sc_paddr != bootaddr) bootpart = -1; /* invalid flag to dk_establish */ - config_found(self, &sc->sc_link, scsiprint); + + for (bus = 0; bus < 2; bus++) { + if (sc->sc_id[bus] < 0) + continue; + + config_found(self, &sc->sc_link[bus], scsiprint); + } + bootpart = tmp; /* restore old value */ } @@ -208,10 +231,16 @@ int do_vspoll(struct vs_softc *sc, struct scsi_xfer *xs, int to, int canreset) { int i; - int crsw; + int crsw, bus; - if (to <= 0 ) to = 50000; - /* use cmd_wait values? */ + if (xs != NULL) + bus = !!(xs->sc_link->flags & SDEV_2NDBUS); + else + bus = -1; + + /* XXX use cmd_wait values */ + if (to <= 0) + to = 50000; i = 10000; while (((crsw = CRSW) & (M_CRSW_CRBV | M_CRSW_CC)) == 0) { @@ -220,7 +249,7 @@ do_vspoll(struct vs_softc *sc, struct scsi_xfer *xs, int to, int canreset) --to; if (to <= 0) { if (canreset) { - vs_reset(sc); + vs_reset(sc, bus); vs_resync(sc); } if (xs == NULL) @@ -283,7 +312,7 @@ thaw_all_queues(struct vs_softc *sc) { int i; - for (i = 1; i <= 7; i++) + for (i = 1; i < NUM_WQ ; i++) thaw_queue(sc, i); } @@ -291,18 +320,18 @@ void vs_scsidone(struct vs_softc *sc, struct scsi_xfer *xs, int stat) { int tgt; + + tgt = vs_queue_number(xs->sc_link, sc); xs->status = stat; while (xs->status == SCSI_CHECK) { vs_chksense(xs); - tgt = vs_queue_number(xs->sc_link->target, sc->sc_pid); thaw_queue(sc, tgt); } - tgt = vs_queue_number(xs->sc_link->target, sc->sc_pid); xs->flags |= ITSDONE; - thaw_queue(sc, tgt); + scsi_done(xs); } @@ -336,7 +365,8 @@ vs_scsicmd(struct scsi_xfer *xs) (u_int8_t *)xs->cmd, xs->cmdlen); vs_write(2, iopb + IOPB_CMD, IOPB_PASSTHROUGH); - vs_write(2, iopb + IOPB_UNIT, IOPB_UNIT_VALUE(slp->target, slp->lun)); + vs_write(2, iopb + IOPB_UNIT, + IOPB_UNIT_VALUE(!!(slp->flags & SDEV_2NDBUS), slp->target, slp->lun)); vs_write(1, iopb + IOPB_NVCT, sc->sc_nvec); vs_write(1, iopb + IOPB_EVCT, sc->sc_evec); @@ -372,7 +402,7 @@ vs_scsicmd(struct scsi_xfer *xs) vs_write(2, cqep + CQE_IOPB_ADDR, iopb); vs_write(1, cqep + CQE_IOPB_LENGTH, iopb_len); vs_write(1, cqep + CQE_WORK_QUEUE, - flags & SCSI_POLL ? 0 : vs_queue_number(slp->target, sc->sc_pid)); + flags & SCSI_POLL ? 0 : vs_queue_number(slp, sc)); MALLOC(m328_cmd, M328_CMD*, sizeof(M328_CMD), M_DEVBUF, M_WAITOK); @@ -427,7 +457,8 @@ vs_chksense(struct scsi_xfer *xs) mce_iopb_write(2, IOPB_ADDR, ADDR_MOD); mce_iopb_write(4, IOPB_BUFF, kvtop((vaddr_t)&xs->sense)); mce_iopb_write(4, IOPB_LENGTH, sizeof(struct scsi_sense_data)); - mce_iopb_write(2, IOPB_UNIT, IOPB_UNIT_VALUE(slp->target, slp->lun)); + mce_iopb_write(2, IOPB_UNIT, + IOPB_UNIT_VALUE(!!(slp->flags & SDEV_2NDBUS), slp->target, slp->lun)); vs_bzero(sh_MCE, CQE_SIZE); mce_write(2, CQE_IOPB_ADDR, sh_MCE_IOPB); @@ -513,13 +544,15 @@ vs_initialize(struct vs_softc *sc) } /* initialize channels id */ - sc->sc_pid = csb_read(1, CSB_PID); - sc->sc_sid = -1; + sc->sc_id[0] = csb_read(1, CSB_PID); + sc->sc_id[1] = -1; switch (dbid = csb_read(1, CSB_DBID)) { case DBID_SCSI2: case DBID_SCSI: +#if 0 printf("daughter board, "); - sc->sc_sid = csb_read(1, CSB_SID); +#endif + sc->sc_id[1] = csb_read(1, CSB_SID); break; case DBID_PRINTER: printf("printer port, "); @@ -539,8 +572,8 @@ vs_initialize(struct vs_softc *sc) cib_write(2, CIB_BURST, 0); cib_write(2, CIB_NVECT, (sc->sc_ipl << 8) | sc->sc_nvec); cib_write(2, CIB_EVECT, (sc->sc_ipl << 8) | sc->sc_evec); - cib_write(2, CIB_PID, sc->sc_pid); - cib_write(2, CIB_SID, 0); /* disable second channel */ + cib_write(2, CIB_PID, 0x08); /* XXX default */ + cib_write(2, CIB_SID, 0x08); cib_write(2, CIB_CRBO, sh_CRB); cib_write(4, CIB_SELECT, SELECTION_TIMEOUT); cib_write(4, CIB_WQTIMO, 4); @@ -572,7 +605,7 @@ vs_initialize(struct vs_softc *sc) do_vspoll(sc, NULL, 0, 1); /* initialize work queues */ - for (i = 1; i < 8; i++) { + for (i = 1; i < NUM_WQ; i++) { vs_bzero(sh_MCE_IOPB, IOPB_LONG_SIZE); mce_iopb_write(2, WQCF_CMD, CNTR_INIT_WORKQ); mce_iopb_write(2, WQCF_OPTION, 0); @@ -847,14 +880,30 @@ vs_clear_return_info(struct vs_softc *sc) /* * Choose the work queue number for a specific target. * - * Targets on the primary channel should be mapped to queues 1-7, - * so we assign each target the queue matching its own number, except for - * target zero which gets assigned to the queue matching the controller id. + * Targets on the primary channel are mapped to queues 1-7, while targets + * on the secondary channel are mapped to queues 8-14. + * To do so, we assign each target the queue matching its own number, + * plus eight on the secondary bus, except for target 0 on the first channel + * and 7 on the secondary channel which gets assigned to the queue matching + * the controller id. */ -static int -vs_queue_number(int target, int host) +int +vs_queue_number(struct scsi_link *sl, struct vs_softc *sc) { - return target == 0 ? host : target; + int bus; + + bus = !!(sl->flags & SDEV_2NDBUS); + + if (sl->target == sc->sc_id[bus]) + return 0; + + if (bus == 0) + return sl->target == 0 ? sc->sc_id[bus] : sl->target; + else + if (sl->target > sc->sc_id[bus]) + return 8 + sl->target - 1; + else + return 8 + sl->target; } /* diff --git a/sys/arch/mvme88k/dev/vsreg.h b/sys/arch/mvme88k/dev/vsreg.h index 0e45179e438..b5a5664882a 100644 --- a/sys/arch/mvme88k/dev/vsreg.h +++ b/sys/arch/mvme88k/dev/vsreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vsreg.h,v 1.11 2004/07/19 20:35:37 miod Exp $ */ +/* $OpenBSD: vsreg.h,v 1.12 2004/07/20 20:32:02 miod Exp $ */ /* * Copyright (c) 2004, Miodrag Vallat. * Copyright (c) 1999 Steve Murphree, Jr. @@ -56,6 +56,7 @@ #define NUM_CQE 10 #define NUM_IOPB NUM_CQE +#define NUM_WQ 15 /* * Master Control Status Block (MCSB) @@ -341,7 +342,8 @@ #define CNTR_ISSUE_ABORT 0x4e /* abort has been issued */ #define CNTR_DOWNLOAD_FIRMWARE 0x4f /* download firmware (COUGAR) */ -#define IOPB_UNIT_VALUE(target, lun) ((lun) << 3 | (target & 7)) +#define IOPB_UNIT_VALUE(bus, target, lun) \ + (((bus) << 6) | ((lun) << 3) | (target & 7)) /* * Memory types diff --git a/sys/arch/mvme88k/dev/vsvar.h b/sys/arch/mvme88k/dev/vsvar.h index 27b9ac7ce79..7c606636f6d 100644 --- a/sys/arch/mvme88k/dev/vsvar.h +++ b/sys/arch/mvme88k/dev/vsvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vsvar.h,v 1.14 2004/07/02 14:00:43 miod Exp $ */ +/* $OpenBSD: vsvar.h,v 1.15 2004/07/20 20:32:02 miod Exp $ */ /* * Copyright (c) 2004, Miodrag Vallat. * Copyright (c) 1999 Steve Murphree, Jr. @@ -100,8 +100,8 @@ struct vs_softc { char sc_intrname_e[16 + 4]; int sc_ipl; int sc_evec, sc_nvec; - int sc_pid, sc_sid; - struct scsi_link sc_link; + int sc_id[2]; + struct scsi_link sc_link[2]; }; /* Access macros */ |