diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/ciss.c | 70 | ||||
-rw-r--r-- | sys/dev/ic/cissreg.h | 23 |
2 files changed, 78 insertions, 15 deletions
diff --git a/sys/dev/ic/ciss.c b/sys/dev/ic/ciss.c index 6fb9f8fd970..7fb0f4f6221 100644 --- a/sys/dev/ic/ciss.c +++ b/sys/dev/ic/ciss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ciss.c,v 1.33 2009/02/16 21:19:06 miod Exp $ */ +/* $OpenBSD: ciss.c,v 1.34 2009/04/29 08:24:26 reyk Exp $ */ /* * Copyright (c) 2005,2006 Michael Shalayeff @@ -332,9 +332,14 @@ ciss_attach(struct ciss_softc *sc) sc->maxunits = inq->numld; sc->nbus = inq->nscsi_bus; sc->ndrives = inq->buswidth? inq->buswidth : 256; - printf(": %d LD%s, HW rev %d, FW %4.4s/%4.4s\n", + printf(": %d LD%s, HW rev %d, FW %4.4s/%4.4s", inq->numld, inq->numld == 1? "" : "s", inq->hw_rev, inq->fw_running, inq->fw_stored); + if (sc->cfg.methods & CISS_METH_FIFO64) + printf(", 64bit fifo"); + else if (sc->cfg.methods & CISS_METH_FIFO64_RRO) + printf(", 64bit fifo rro"); + printf("\n"); CISS_UNLOCK_SCRATCH(sc, lock); @@ -481,6 +486,7 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait) struct ciss_cmd *cmd = &ccb->ccb_cmd; struct ciss_ccb *ccb1; bus_dmamap_t dmap = ccb->ccb_dmamap; + u_int64_t addr; u_int32_t id; int i, tohz, error = 0; @@ -538,7 +544,18 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait) TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ccb_link); ccb->ccb_state = CISS_CCB_ONQ; CISS_DPRINTF(CISS_D_CMD, ("submit=0x%x ", cmd->id)); - bus_space_write_4(sc->iot, sc->ioh, CISS_INQ, ccb->ccb_cmdpa); + if (sc->cfg.methods & (CISS_METH_FIFO64|CISS_METH_FIFO64_RRO)) { + /* + * Write the upper 32bits immediately before the lower + * 32bits and set bit 63 to indicate 64bit FIFO mode. + */ + addr = (u_int64_t)ccb->ccb_cmdpa; + bus_space_write_4(sc->iot, sc->ioh, CISS_INQ64_HI, + (addr >> 32) | 0x80000000); + bus_space_write_4(sc->iot, sc->ioh, CISS_INQ64_LO, + addr & 0x00000000ffffffffULL); + } else + bus_space_write_4(sc->iot, sc->ioh, CISS_INQ, ccb->ccb_cmdpa); if (wait & SCSI_POLL) { struct timeval tv; @@ -576,15 +593,37 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait) continue; } - if ((id = bus_space_read_4(sc->iot, sc->ioh, - CISS_OUTQ)) == 0xffffffff) { - CISS_DPRINTF(CISS_D_CMD, ("Q")); - continue; + if (sc->cfg.methods & CISS_METH_FIFO64) { + if (bus_space_read_4(sc->iot, sc->ioh, + CISS_OUTQ64_HI) == 0xffffffff) { + CISS_DPRINTF(CISS_D_CMD, ("Q")); + continue; + } + id = bus_space_read_4(sc->iot, sc->ioh, + CISS_OUTQ64_LO); + } else if (sc->cfg.methods & + CISS_METH_FIFO64_RRO) { + id = bus_space_read_4(sc->iot, sc->ioh, + CISS_OUTQ64_LO); + if (id == 0xffffffff) { + CISS_DPRINTF(CISS_D_CMD, ("Q")); + continue; + } + (void)bus_space_read_4(sc->iot, + sc->ioh, CISS_OUTQ64_HI); + } else { + id = bus_space_read_4(sc->iot, sc->ioh, + CISS_OUTQ); + if (id == 0xffffffff) { + CISS_DPRINTF(CISS_D_CMD, ("Q")); + continue; + } } CISS_DPRINTF(CISS_D_CMD, ("got=0x%x ", id)); ccb1 = sc->ccbs + (id >> 2) * sc->ccblen; ccb1->ccb_cmd.id = htole32(id); + ccb1->ccb_cmd.id_hi = htole32(0); } error = ciss_done(ccb1); @@ -940,6 +979,7 @@ ciss_intr(void *v) struct ciss_softc *sc = v; struct ciss_ccb *ccb; ciss_lock_t lock; + bus_size_t reg; u_int32_t id; int hit = 0; @@ -949,11 +989,23 @@ ciss_intr(void *v) return 0; lock = CISS_LOCK(sc); - while ((id = bus_space_read_4(sc->iot, sc->ioh, CISS_OUTQ)) != - 0xffffffff) { + if (sc->cfg.methods & CISS_METH_FIFO64) + reg = CISS_OUTQ64_HI; + else if (sc->cfg.methods & CISS_METH_FIFO64_RRO) + reg = CISS_OUTQ64_LO; + else + reg = CISS_OUTQ; + while ((id = bus_space_read_4(sc->iot, sc->ioh, reg)) != 0xffffffff) { + if (reg == CISS_OUTQ64_HI) + id = bus_space_read_4(sc->iot, sc->ioh, + CISS_OUTQ64_LO); + else if (reg == CISS_OUTQ64_LO) + (void)bus_space_read_4(sc->iot, sc->ioh, + CISS_OUTQ64_HI); ccb = sc->ccbs + (id >> 2) * sc->ccblen; ccb->ccb_cmd.id = htole32(id); + ccb->ccb_cmd.id_hi = htole32(0); /* ignore the upper 32bits */ if (ccb->ccb_state == CISS_CCB_POLL) { ccb->ccb_state = CISS_CCB_ONQ; wakeup(ccb); diff --git a/sys/dev/ic/cissreg.h b/sys/dev/ic/cissreg.h index 2ffe9dc4ee3..5f6a5e5c0b1 100644 --- a/sys/dev/ic/cissreg.h +++ b/sys/dev/ic/cissreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cissreg.h,v 1.9 2007/11/26 19:13:22 dlg Exp $ */ +/* $OpenBSD: cissreg.h,v 1.10 2009/04/29 08:24:26 reyk Exp $ */ /* * Copyright (c) 2005,2006 Michael Shalayeff @@ -30,6 +30,12 @@ #define CISS_CFG_BAR 0xb4 #define CISS_CFG_OFF 0xb8 +/* 64bit FIFO mode input/output post queues */ +#define CISS_INQ64_LO 0xc0 +#define CISS_INQ64_HI 0xc4 +#define CISS_OUTQ64_LO 0xc8 +#define CISS_OUTQ64_HI 0xcc + #define CISS_DRVMAP_SIZE (128 / 8) #define CISS_CMD_CTRL_GET 0x26 @@ -64,10 +70,15 @@ struct ciss_config { #define CISS_SIGNATURE (*(u_int32_t *)"CISS") u_int32_t version; u_int32_t methods; -#define CISS_METH_READY 0x0001 -#define CISS_METH_SIMPL 0x0002 -#define CISS_METH_PERF 0x0004 -#define CISS_METH_EMQ 0x0008 +#define CISS_METH_READY 0x00000001 /* indicate to accept commands */ +#define CISS_METH_SIMPL 0x00000002 /* simple mode */ +#define CISS_METH_PERF 0x00000004 /* performant mode */ +#define CISS_METH_EMQ 0x00000008 /* MEMQ method */ +#define CISS_METH_BIT63 0x08000000 /* address bit 63 is valid */ +#define CISS_METH_FIFO64_RRO 0x10000000 /* 64bit FIFO reverse read order */ +#define CISS_METH_SHORT_TAG 0x20000000 /* short 4 byte tag support */ +#define CISS_METH_MSIX 0x40000000 /* directed MSI-X support */ +#define CISS_METH_FIFO64 0x80000000 /* 64bit FIFO support */ u_int32_t amethod; u_int32_t rmethod; u_int32_t paddr_lim; @@ -465,7 +476,7 @@ struct ciss_error { struct ciss_ccb { TAILQ_ENTRY(ciss_ccb) ccb_link; struct ciss_softc *ccb_sc; - paddr_t ccb_cmdpa; + u_int64_t ccb_cmdpa; enum { CISS_CCB_FREE = 0x01, CISS_CCB_READY = 0x02, |