summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/ciss.c70
-rw-r--r--sys/dev/ic/cissreg.h23
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,