parent
11beb626a3
commit
6b629de220
|
@ -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 @@ 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");
|
||||
|
||||
mutex_exit(&sc->sc_mutex_scratch);
|
||||
|
||||
callout_init(&sc->sc_hb, 0);
|
||||
|
@ -423,7 +429,7 @@ ciss_shutdown(void *v)
|
|||
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 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait)
|
|||
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 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait)
|
|||
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 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait)
|
|||
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 @@ ciss_error(struct ciss_ccb *ccb)
|
|||
|
||||
switch ((rv = le16toh(err->cmd_stat))) {
|
||||
case CISS_ERR_OK:
|
||||
rv = 0;
|
||||
break;
|
||||
|
||||
case CISS_ERR_INVCMD:
|
||||
|
@ -657,10 +700,12 @@ ciss_error(struct ciss_ccb *ccb)
|
|||
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 @@ ciss_error(struct ciss_ccb *ccb)
|
|||
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 @@ ciss_error(struct ciss_ccb *ccb)
|
|||
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 @@ ciss_error(struct ciss_ccb *ccb)
|
|||
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 @@ ciss_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req,
|
|||
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 @@ ciss_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req,
|
|||
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 @@ ciss_intr(void *v)
|
|||
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 @@ ciss_heartbeat(void *v)
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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 @@ struct ciss_config {
|
|||
#define CISS_SIGNATURE (*(const 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;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* $NetBSD: cissvar.h,v 1.5 2012/10/27 17:18:19 chs Exp $ */
|
||||
/* $OpenBSD: cissvar.h,v 1.2 2005/09/07 04:00:16 mickey Exp $ */
|
||||
/* $NetBSD: cissvar.h,v 1.6 2013/10/12 16:52:21 christos Exp $ */
|
||||
/* $OpenBSD: cissvar.h,v 1.15 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
|
||||
|
@ -63,6 +63,7 @@ struct ciss_softc {
|
|||
|
||||
bus_space_handle_t cfg_ioh;
|
||||
|
||||
int fibrillation;
|
||||
struct ciss_config cfg;
|
||||
int cfgoff;
|
||||
u_int32_t iem;
|
||||
|
|
Loading…
Reference in New Issue