summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2015-01-09 11:17:30 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2015-01-09 11:17:30 +0000
commit754a0d14f6e0f0c767d040680e9ed8dfa2c67865 (patch)
tree8259f27bbd91c2ce459679be05f2d821f68a570a
parent738b6e46b93385fa04dc3fd8d04089161141acac (diff)
Add support DIOC{G,S}CACHE to mfi(4). Cache of disk on mfi(4) will
be enabled by default. Also if the controller doesn't have any RAM, the cache on the physical disk will be enabled. discuss with jsg tsubai ok dlg
-rw-r--r--sys/dev/ic/mfi.c100
-rw-r--r--sys/dev/ic/mfireg.h14
2 files changed, 108 insertions, 6 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index a4d355ec719..699f7458926 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.158 2014/12/19 07:23:57 deraadt Exp $ */
+/* $OpenBSD: mfi.c,v 1.159 2015/01/09 11:17:29 yasuoka Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -27,6 +27,7 @@
#include <sys/malloc.h>
#include <sys/rwlock.h>
#include <sys/sensors.h>
+#include <sys/dkio.h>
#include <sys/pool.h>
#include <machine/bus.h>
@@ -58,6 +59,7 @@ struct cfdriver mfi_cd = {
void mfi_scsi_cmd(struct scsi_xfer *);
int mfi_scsi_ioctl(struct scsi_link *, u_long, caddr_t, int);
+int mfi_ioctl_cache(struct scsi_link *, u_long, struct dk_cache *);
void mfiminphys(struct buf *bp, struct scsi_link *sl);
void mfi_pd_scsi_cmd(struct scsi_xfer *);
@@ -1419,10 +1421,98 @@ mfi_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag)
DNPRINTF(MFI_D_IOCTL, "%s: mfi_scsi_ioctl\n", DEVNAME(sc));
- if (sc->sc_ioctl)
- return (sc->sc_ioctl(link->adapter_softc, cmd, addr));
- else
- return (ENOTTY);
+ switch (cmd) {
+ case DIOCGCACHE:
+ case DIOCSCACHE:
+ return (mfi_ioctl_cache(link, cmd, (struct dk_cache *)addr));
+ break;
+
+ default:
+ if (sc->sc_ioctl)
+ return (sc->sc_ioctl(link->adapter_softc, cmd, addr));
+ break;
+ }
+
+ return (ENOTTY);
+}
+
+int
+mfi_ioctl_cache(struct scsi_link *link, u_long cmd, struct dk_cache *dc)
+{
+ struct mfi_softc *sc = (struct mfi_softc *)link->adapter_softc;
+ int rv, wrenable, rdenable;
+ struct mfi_ld_prop ldp;
+ uint8_t mbox[MFI_MBOX_SIZE];
+
+ if (mfi_get_info(sc)) {
+ rv = EIO;
+ goto done;
+ }
+
+ if (!sc->sc_ld[link->target].ld_present) {
+ rv = EIO;
+ goto done;
+ }
+
+ mbox[0] = link->target;
+ if ((rv = mfi_mgmt(sc, MR_DCMD_LD_GET_PROPERTIES, MFI_DATA_IN,
+ sizeof(ldp), &ldp, mbox)) != 0)
+ goto done;
+
+ if (sc->sc_info.mci_memory_size > 0) {
+ wrenable = ISSET(ldp.mlp_cur_cache_policy,
+ MR_LD_CACHE_ALLOW_WRITE_CACHE)? 1 : 0;
+ rdenable = ISSET(ldp.mlp_cur_cache_policy,
+ MR_LD_CACHE_ALLOW_READ_CACHE)? 1 : 0;
+ } else {
+ wrenable = ISSET(ldp.mlp_diskcache_policy,
+ MR_LD_DISK_CACHE_ENABLE)? 1 : 0;
+ rdenable = 0;
+ }
+
+ if (cmd == DIOCGCACHE) {
+ dc->wrcache = wrenable;
+ dc->rdcache = rdenable;
+ goto done;
+ } /* else DIOCSCACHE */
+
+ if (((dc->wrcache) ? 1 : 0) == wrenable &&
+ ((dc->rdcache) ? 1 : 0) == rdenable)
+ goto done;
+
+ mbox[0] = ldp.mlp_ld.mld_target;
+ mbox[1] = ldp.mlp_ld.mld_res;
+ *(uint16_t *)&mbox[2] = ldp.mlp_ld.mld_seq;
+
+ if (sc->sc_info.mci_memory_size > 0) {
+ if (dc->rdcache)
+ SET(ldp.mlp_cur_cache_policy,
+ MR_LD_CACHE_ALLOW_READ_CACHE);
+ else
+ CLR(ldp.mlp_cur_cache_policy,
+ MR_LD_CACHE_ALLOW_READ_CACHE);
+ if (dc->wrcache)
+ SET(ldp.mlp_cur_cache_policy,
+ MR_LD_CACHE_ALLOW_WRITE_CACHE);
+ else
+ CLR(ldp.mlp_cur_cache_policy,
+ MR_LD_CACHE_ALLOW_WRITE_CACHE);
+ } else {
+ if (dc->rdcache) {
+ rv = EOPNOTSUPP;
+ goto done;
+ }
+ if (dc->wrcache)
+ ldp.mlp_diskcache_policy = MR_LD_DISK_CACHE_ENABLE;
+ else
+ ldp.mlp_diskcache_policy = MR_LD_DISK_CACHE_DISABLE;
+ }
+
+ if ((rv = mfi_mgmt(sc, MR_DCMD_LD_SET_PROPERTIES, MFI_DATA_OUT,
+ sizeof(ldp), &ldp, mbox)) != 0)
+ goto done;
+done:
+ return (rv);
}
#if NBIO > 0
diff --git a/sys/dev/ic/mfireg.h b/sys/dev/ic/mfireg.h
index d2a762ea89f..64fb22f34dc 100644
--- a/sys/dev/ic/mfireg.h
+++ b/sys/dev/ic/mfireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfireg.h,v 1.41 2014/08/15 02:27:02 yasuoka Exp $ */
+/* $OpenBSD: mfireg.h,v 1.42 2015/01/09 11:17:29 yasuoka Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -119,6 +119,7 @@
#define MR_DCMD_LD_GET_LIST 0x03010000
#define MR_DCMD_LD_GET_INFO 0x03020000
#define MR_DCMD_LD_GET_PROPERTIES 0x03030000
+#define MR_DCMD_LD_SET_PROPERTIES 0x03040000
#define MR_DCMD_CONF_GET 0x04010000
#define MR_DCMD_BBU_GET_STATUS 0x05010000
#define MR_DCMD_BBU_GET_CAPACITY_INFO 0x05020000
@@ -136,6 +137,17 @@
#define MR_DCMD_SPEAKER_SILENCE 0x01030400
#define MR_DCMD_SPEAKER_TEST 0x01030500
+#define MR_LD_CACHE_WRITE_BACK 0x01
+#define MR_LD_CACHE_WRITE_ADAPTIVE 0x02
+#define MR_LD_CACHE_READ_AHEAD 0x04
+#define MR_LD_CACHE_READ_ADAPTIVE 0x08
+#define MR_LD_CACHE_WRITE_CACHE_BAD_BBU 0x10
+#define MR_LD_CACHE_ALLOW_WRITE_CACHE 0x20
+#define MR_LD_CACHE_ALLOW_READ_CACHE 0x40
+
+#define MR_LD_DISK_CACHE_ENABLE 0x01
+#define MR_LD_DISK_CACHE_DISABLE 0x02
+
/* mailbox bytes in direct command */
#define MFI_MBOX_SIZE 12