summaryrefslogtreecommitdiff
path: root/sys/dev/pci/mfii.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-01-09 03:34:41 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-01-09 03:34:41 +0000
commit3378634251e12f50a0c9361420a6dc39b51d63fd (patch)
treef37bfb4d916b94f51902b99da5e3cc153638213b /sys/dev/pci/mfii.c
parent228a94babcea791a098de943b14ff520a205780f (diff)
implement mfii_scsi_cmd_io for handling actual io. previously i got
away with being lazy and just passing everything to the vanilla scsi cdb path. sending io via the cdb path with chained sgls seems to trigger a firmware fault on the new invader boards. sending the same io via the ldio path works fine though. tested on invader and thunderbolt boards: mfii0 at pci1 dev 0 function 0 "Symbios Logic MegaRAID SAS3108" rev 0x02: msi mfii0: "PERC H730 Mini", firmware 25.2.1.0037, 1024MB cache mfii0 at pci1 dev 0 function 0 "Symbios Logic MegaRAID SAS2208" rev 0x05: msi mfii0: "PERC H710 Mini", firmware 21.3.0-0009, 512MB cache ok jmatthew@
Diffstat (limited to 'sys/dev/pci/mfii.c')
-rw-r--r--sys/dev/pci/mfii.c69
1 files changed, 58 insertions, 11 deletions
diff --git a/sys/dev/pci/mfii.c b/sys/dev/pci/mfii.c
index eb7645e1dc4..153d6c50ba4 100644
--- a/sys/dev/pci/mfii.c
+++ b/sys/dev/pci/mfii.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfii.c,v 1.23 2015/01/07 10:26:48 dlg Exp $ */
+/* $OpenBSD: mfii.c,v 1.24 2015/01/09 03:34:40 dlg Exp $ */
/*
* Copyright (c) 2012 David Gwynne <dlg@openbsd.org>
@@ -64,6 +64,7 @@ struct mfii_request_descr {
} __packed;
#define MFII_RAID_CTX_IO_TYPE_SYSPD (0x1 << 4)
+#define MFII_RAID_CTX_TYPE_CUDA (0x2 << 4)
struct mfii_raid_context {
u_int8_t type_nseg;
@@ -71,6 +72,10 @@ struct mfii_raid_context {
u_int16_t timeout_value;
u_int8_t reg_lock_flags;
+#define MFII_RAID_CTX_RL_FLAGS_SEQNO_EN (0x08)
+#define MFII_RAID_CTX_RL_FLAGS_CPU0 (0x00)
+#define MFII_RAID_CTX_RL_FLAGS_CPU1 (0x10)
+#define MFII_RAID_CTX_RL_FLAGS_CUDA (0x80)
u_int8_t _reserved2;
u_int16_t virtual_disk_target_id;
@@ -201,6 +206,9 @@ struct mfii_pd_softc {
};
struct mfii_iop {
+ u_int8_t ldio_req_type;
+ u_int8_t ldio_ctx_type_nseg;
+ u_int8_t ldio_ctx_reg_lock_flags;
u_int8_t sge_flag_chain;
u_int8_t sge_flag_eol;
};
@@ -332,11 +340,20 @@ int mfii_pd_scsi_cmd_cdb(struct mfii_softc *,
#define mfii_fw_state(_sc) mfii_read((_sc), MFI_OSP)
const struct mfii_iop mfii_iop_thunderbolt = {
+ MFII_REQ_TYPE_LDIO,
+ 0,
+ 0,
MFII_SGE_CHAIN_ELEMENT | MFII_SGE_ADDR_IOCPLBNTA,
0
};
+/*
+ * a lot of these values depend on us not implementing fastpath yet.
+ */
const struct mfii_iop mfii_iop_25 = {
+ MFII_REQ_TYPE_NO_LOCK,
+ MFII_RAID_CTX_TYPE_CUDA | 0x1,
+ MFII_RAID_CTX_RL_FLAGS_CPU0, /* | MFII_RAID_CTX_RL_FLAGS_SEQNO_EN */
MFII_SGE_CHAIN_ELEMENT,
MFII_SGE_END_OF_LIST
};
@@ -1332,7 +1349,6 @@ mfii_scsi_cmd(struct scsi_xfer *xs)
ccb->ccb_data = xs->data;
ccb->ccb_len = xs->datalen;
-#if 0
switch (xs->cmd->opcode) {
case READ_COMMAND:
case READ_BIG:
@@ -1348,13 +1364,10 @@ mfii_scsi_cmd(struct scsi_xfer *xs)
break;
default:
-#endif
if (mfii_scsi_cmd_cdb(sc, xs) != 0)
goto stuffup;
-#if 0
break;
}
-#endif
xs->error = XS_NOERROR;
xs->resid = 0;
@@ -1406,16 +1419,50 @@ mfii_scsi_cmd_done(struct mfii_softc *sc, struct mfii_ccb *ccb)
int
mfii_scsi_cmd_io(struct mfii_softc *sc, struct scsi_xfer *xs)
{
+ struct scsi_link *link = xs->sc_link;
struct mfii_ccb *ccb = xs->io;
- u_int64_t blkno;
- u_int32_t nblks;
+ struct mpii_msg_scsi_io *io = ccb->ccb_request;
+ struct mfii_raid_context *ctx = (struct mfii_raid_context *)(io + 1);
- ccb->ccb_req.flags = MFII_REQ_TYPE_LDIO;
- ccb->ccb_req.smid = letoh16(ccb->ccb_smid);
+ io->dev_handle = htole16(link->target);
+ io->function = MFII_FUNCTION_LDIO_REQUEST;
+ io->sense_buffer_low_address = htole32(ccb->ccb_sense_dva);
+ io->sgl_flags = htole16(0x02); /* XXX */
+ io->sense_buffer_length = sizeof(xs->sense);
+ io->sgl_offset0 = (sizeof(*io) + sizeof(*ctx)) / 4;
+ io->data_length = htole32(xs->datalen);
+ io->io_flags = htole16(xs->cmdlen);
+ switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
+ case SCSI_DATA_IN:
+ ccb->ccb_direction = MFII_DATA_IN;
+ io->direction = MPII_SCSIIO_DIR_READ;
+ break;
+ case SCSI_DATA_OUT:
+ ccb->ccb_direction = MFII_DATA_OUT;
+ io->direction = MPII_SCSIIO_DIR_WRITE;
+ break;
+ default:
+ ccb->ccb_direction = MFII_DATA_NONE;
+ io->direction = MPII_SCSIIO_DIR_NONE;
+ break;
+ }
+ memcpy(io->cdb, xs->cmd, xs->cmdlen);
- scsi_cmd_rw_decode(xs->cmd, &blkno, &nblks);
+ ctx->type_nseg = sc->sc_iop->ldio_ctx_type_nseg;
+ ctx->timeout_value = htole16(0x14); /* XXX */
+ ctx->reg_lock_flags = sc->sc_iop->ldio_ctx_reg_lock_flags;
+ ctx->virtual_disk_target_id = htole16(link->target);
- return (1);
+ if (mfii_load_ccb(sc, ccb, ctx + 1,
+ ISSET(xs->flags, SCSI_NOSLEEP)) != 0)
+ return (1);
+
+ ctx->num_sge = (ccb->ccb_len == 0) ? 0 : ccb->ccb_dmamap->dm_nsegs;
+
+ ccb->ccb_req.flags = sc->sc_iop->ldio_req_type;
+ ccb->ccb_req.smid = letoh16(ccb->ccb_smid);
+
+ return (0);
}
int