Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic - add 64 bit fifo support
details: https://anonhg.NetBSD.org/src/rev/ef023cf5737e
branches: trunk
changeset: 790454:ef023cf5737e
user: christos <christos%NetBSD.org@localhost>
date: Sat Oct 12 16:52:21 2013 +0000
description:
- add 64 bit fifo support
- handle fibrilation better
diffstat:
sys/dev/ic/ciss.c | 118 +++++++++++++++++++++++++++++++++++++++++---------
sys/dev/ic/cissreg.h | 25 +++++++---
sys/dev/ic/cissvar.h | 7 +-
3 files changed, 118 insertions(+), 32 deletions(-)
diffs (truncated from 338 to 300 lines):
diff -r fc2e29884f5e -r ef023cf5737e sys/dev/ic/ciss.c
--- a/sys/dev/ic/ciss.c Sat Oct 12 16:49:00 2013 +0000
+++ b/sys/dev/ic/ciss.c Sat Oct 12 16:52:21 2013 +0000
@@ -1,8 +1,8 @@
-/* $NetBSD: ciss.c,v 1.29 2012/10/27 17:18:19 chs Exp $ */
-/* $OpenBSD: ciss.c,v 1.14 2006/03/13 16:02:23 mickey Exp $ */
+/* $NetBSD: ciss.c,v 1.30 2013/10/12 16:52:21 christos Exp $ */
+/* $OpenBSD: ciss.c,v 1.68 2013/05/30 16:15:02 deraadt Exp $ */
/*
- * Copyright (c) 2005 Michael Shalayeff
+ * Copyright (c) 2005,2006 Michael Shalayeff
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ciss.c,v 1.29 2012/10/27 17:18:19 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ciss.c,v 1.30 2013/10/12 16:52:21 christos Exp $");
#include "bio.h"
@@ -323,10 +323,16 @@
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");
+
mutex_exit(&sc->sc_mutex_scratch);
callout_init(&sc->sc_hb, 0);
@@ -423,7 +429,7 @@
static void
cissminphys(struct buf *bp)
{
-#if 0 /* TOSO */
+#if 0 /* TODO */
#define CISS_MAXFER (PAGE_SIZE * (sc->maxsg + 1))
if (bp->b_bcount > CISS_MAXFER)
bp->b_bcount = CISS_MAXFER;
@@ -445,6 +451,7 @@
struct ciss_ccb *ccb1;
bus_dmamap_t dmap = ccb->ccb_dmamap;
u_int32_t id;
+ u_int64_t addr;
int i, tohz, error = 0;
if (ccb->ccb_state != CISS_CCB_READY) {
@@ -505,7 +512,19 @@
mutex_exit(&sc->sc_mutex);
ccb->ccb_state = CISS_CCB_ONQ;
CISS_DPRINTF(CISS_D_CMD, ("submit=0x%x ", cmd->id));
- bus_space_write_4(sc->sc_iot, sc->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->sc_iot, sc->sc_ioh, CISS_INQ64_HI,
+ (addr >> 32) | 0x80000000);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_INQ64_LO,
+ addr & 0x00000000ffffffffULL);
+ } else
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_INQ,
+ ccb->ccb_cmdpa);
if (wait & XS_CTL_POLL) {
int etick;
@@ -543,21 +562,44 @@
continue;
}
- if ((id = bus_space_read_4(sc->sc_iot, sc->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->sc_iot,
+ sc->sc_ioh,
+ CISS_OUTQ64_HI) == 0xffffffff) {
+ CISS_DPRINTF(CISS_D_CMD, ("Q"));
+ continue;
+ }
+ id = bus_space_read_4(sc->sc_iot,
+ sc->sc_ioh, CISS_OUTQ64_LO);
+ } else if (sc->cfg.methods &
+ CISS_METH_FIFO64_RRO) {
+ id = bus_space_read_4(sc->sc_iot,
+ sc->sc_ioh, CISS_OUTQ64_LO);
+ if (id == 0xffffffff) {
+ CISS_DPRINTF(CISS_D_CMD, ("Q"));
+ continue;
+ }
+ (void)bus_space_read_4(sc->sc_iot,
+ sc->sc_ioh, CISS_OUTQ64_HI);
+ } else {
+ id = bus_space_read_4(sc->sc_iot,
+ sc->sc_ioh, CISS_OUTQ);
+ if (id == 0xffffffff) {
+ CISS_DPRINTF(CISS_D_CMD, ("Q"));
+ continue;
+ }
}
CISS_DPRINTF(CISS_D_CMD, ("got=0x%x ", id));
ccb1 = (struct ciss_ccb *)
((char *)sc->ccbs + (id >> 2) * sc->ccblen);
ccb1->ccb_cmd.id = htole32(id);
+ ccb1->ccb_cmd.id_hi = htole32(0);
}
error = ciss_done(ccb1);
if (ccb1 == ccb)
- break;
+ return error;
}
/* if never got a chance to be done above... */
@@ -640,6 +682,7 @@
switch ((rv = le16toh(err->cmd_stat))) {
case CISS_ERR_OK:
+ rv = 0;
break;
case CISS_ERR_INVCMD:
@@ -657,10 +700,12 @@
xs->sense.scsi_sense.ascq = 0x0;
xs->error = XS_SENSE;
}
+ rv = EIO;
break;
case CISS_ERR_TMO:
xs->error = XS_TIMEOUT;
+ rv = ETIMEDOUT;
break;
case CISS_ERR_UNRUN:
@@ -668,6 +713,7 @@
xs->resid = le32toh(err->resid);
CISS_DPRINTF(CISS_D_CMD, (" underrun resid=0x%x ",
xs->resid));
+ rv = EIO;
break;
default:
if (xs) {
@@ -679,10 +725,12 @@
sizeof(xs->sense));
CISS_DPRINTF(CISS_D_CMD, (" sense=%02x %02x %02x %02x ",
err->sense[0], err->sense[1], err->sense[2], err->sense[3]));
+ rv = EIO;
break;
case XS_BUSY:
xs->error = XS_BUSY;
+ rv = EBUSY;
break;
default:
@@ -693,10 +741,12 @@
printf("ciss driver stuffup in %s:%d: %s()\n",
__FILE__, __LINE__, __func__);
xs->error = XS_DRIVER_STUFFUP;
+ rv = EIO;
break;
}
xs->resid = le32toh(err->resid);
- }
+ } else
+ rv = EIO;
}
ccb->ccb_cmd.id &= htole32(~3);
@@ -1031,9 +1081,9 @@
if (xs->cmdlen > CISS_MAX_CDB) {
CISS_DPRINTF(CISS_D_CMD, ("CDB too big %p ", xs));
memset(&xs->sense, 0, sizeof(xs->sense));
+ xs->error = XS_SENSE;
printf("ciss driver stuffup in %s:%d: %s()\n",
__FILE__, __LINE__, __func__);
- xs->error = XS_DRIVER_STUFFUP;
scsipi_done(xs);
break;
}
@@ -1056,7 +1106,7 @@
cmd->flags |= CISS_CDB_IN;
else if (xs->xs_control & XS_CTL_DATA_OUT)
cmd->flags |= CISS_CDB_OUT;
- cmd->tmo = xs->timeout < 1000? 1 : xs->timeout / 1000;
+ cmd->tmo = htole16(xs->timeout < 1000? 1 : xs->timeout / 1000);
memset(&cmd->cdb[0], 0, sizeof(cmd->cdb));
memcpy(&cmd->cdb[0], xs->cmd, CISS_MAX_CDB);
CISS_DPRINTF(CISS_D_CMD, ("cmd=%02x %02x %02x %02x %02x %02x ",
@@ -1096,18 +1146,29 @@
struct ciss_softc *sc = v;
struct ciss_ccb *ccb;
u_int32_t id;
+ bus_size_t reg;
int hit = 0;
CISS_DPRINTF(CISS_D_INTR, ("intr "));
- if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_ISR) & sc->iem))
- return 0;
-
- while ((id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ)) !=
+ 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->sc_iot, sc->sc_ioh, reg)) !=
0xffffffff) {
+ if (reg == CISS_OUTQ64_HI)
+ id = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ CISS_OUTQ64_LO);
+ else if (reg == CISS_OUTQ64_LO)
+ (void)bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ CISS_OUTQ64_HI);
ccb = (struct ciss_ccb *) ((char *)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;
mutex_enter(&sc->sc_mutex);
@@ -1131,10 +1192,23 @@
hb = bus_space_read_4(sc->sc_iot, sc->cfg_ioh,
sc->cfgoff + offsetof(struct ciss_config, heartbeat));
- if (hb == sc->heartbeat)
- panic("ciss: dead"); /* XX reset! */
- else
+ if (hb == sc->heartbeat) {
+ sc->fibrillation++;
+ CISS_DPRINTF(CISS_D_ERR, ("%s: fibrillation #%d (value=%d)\n",
+ device_xname(sc->sc_dev), sc->fibrillation, hb));
+ if (sc->fibrillation >= 11) {
+ /* No heartbeat for 33 seconds */
+ panic("%s: dead", device_xname(sc->sc_dev)); /* XXX reset! */
+ }
+ } else {
sc->heartbeat = hb;
+ if (sc->fibrillation) {
+ CISS_DPRINTF(CISS_D_ERR, ("%s: "
+ "fibrillation ended (value=%d)\n",
+ device_xname(sc->sc_dev), hb));
+ }
+ sc->fibrillation = 0;
+ }
callout_schedule(&sc->sc_hb, hz * 3);
}
diff -r fc2e29884f5e -r ef023cf5737e sys/dev/ic/cissreg.h
--- a/sys/dev/ic/cissreg.h Sat Oct 12 16:49:00 2013 +0000
+++ b/sys/dev/ic/cissreg.h Sat Oct 12 16:52:21 2013 +0000
@@ -1,8 +1,8 @@
-/* $NetBSD: cissreg.h,v 1.3 2008/10/18 18:53:20 bouyer Exp $ */
-/* $OpenBSD: cissreg.h,v 1.4 2005/12/13 15:55:59 brad Exp $ */
+/* $NetBSD: cissreg.h,v 1.4 2013/10/12 16:52:21 christos Exp $ */
+/* $OpenBSD: cissreg.h,v 1.11 2010/06/03 01:02:13 dlg Exp $ */
/*
- * Copyright (c) 2005 Michael Shalayeff
+ * Copyright (c) 2005,2006 Michael Shalayeff
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -31,6 +31,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
@@ -65,10 +71,15 @@
#define CISS_SIGNATURE (*(const u_int32_t *)"CISS")
u_int32_t version;
u_int32_t methods;
-#define CISS_METH_READY 0x0001
Home |
Main Index |
Thread Index |
Old Index