summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-03-08 15:13:13 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-03-08 15:13:13 +0000
commitadece212e67baf234e8993136866937f2057c999 (patch)
treeafd976f8138080a150a7de5824c9c20d39735df1 /sys
parenteaa89fd716ef08f5a0ce1b718a9a650eb0a254ae (diff)
Enable DMA bursting. Not sure it actually makes things faster, but both
isp(4) and the linux qla1280 driver seem to do this.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/qlw.c61
-rw-r--r--sys/dev/ic/qlwreg.h18
-rw-r--r--sys/dev/ic/qlwvar.h11
-rw-r--r--sys/dev/pci/qlw_pci.c24
4 files changed, 91 insertions, 23 deletions
diff --git a/sys/dev/ic/qlw.c b/sys/dev/ic/qlw.c
index ed76ab3895f..b523c7e8d9f 100644
--- a/sys/dev/ic/qlw.c
+++ b/sys/dev/ic/qlw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: qlw.c,v 1.4 2014/03/07 22:39:07 kettenis Exp $ */
+/* $OpenBSD: qlw.c,v 1.5 2014/03/08 15:13:12 kettenis Exp $ */
/*
* Copyright (c) 2011 David Gwynne <dlg@openbsd.org>
@@ -93,6 +93,7 @@ struct qlw_ccb *qlw_handle_resp(struct qlw_softc *, u_int16_t);
void qlw_put_data_seg(struct qlw_iocb_seg *, bus_dmamap_t, int);
int qlw_softreset(struct qlw_softc *);
+void qlw_dma_burst_enable(struct qlw_softc *);
void qlw_update_start(struct qlw_softc *, int);
int qlw_async(struct qlw_softc *, u_int16_t);
@@ -225,9 +226,13 @@ qlw_attach(struct qlw_softc *sc)
/* We may need up to 3 request entries per SCSI command. */
sc->sc_maxccbs = sc->sc_maxcmds / 3;
-#if 0
- qlw_write(sc, QLW_CFG1, sc->sc_nvram.isp_config | (1 << 13));
-#endif
+ /* Allegedly the FIFO is busted on the 1040A. */
+ if (sc->sc_isp_type == QLW_ISP1040A)
+ sc->sc_isp_config &= ~QLW_PCI_FIFO_MASK;
+ qlw_write(sc, QLW_CFG1, sc->sc_isp_config);
+
+ if (sc->sc_isp_config & QLW_BURST_ENABLE)
+ qlw_dma_burst_enable(sc);
#if 0
/* set SCSI termination */
@@ -300,16 +305,6 @@ qlw_attach(struct qlw_softc *sc)
}
#endif
-#if 0
- sc->sc_mbox[0] = QLW_MBOX_SET_PCI_CONTROL;
- sc->sc_mbox[1] = 0x0002; /* data dma channel burst enable */
- sc->sc_mbox[2] = 0x0002; /* command dma channel burst enable */
- if (qlw_mbox(sc, 0x0007, 0x0001)) {
- printf("couldn't set PCI control: %x\n", sc->sc_mbox[0]);
- return (ENXIO);
- }
-#endif
-
sc->sc_mbox[0] = QLW_MBOX_SET_TAG_AGE_LIMIT;
sc->sc_mbox[1] = 8;
sc->sc_mbox[2] = 8;
@@ -1090,11 +1085,7 @@ qlw_softreset(struct qlw_softc *sc)
/* reset risc processor */
qlw_host_cmd(sc, QLW_HOST_CMD_RESET);
delay(100);
-
qlw_write(sc, QLW_SEMA, 0);
-
- qlw_write(sc, QLW_CFG1, qlw_read(sc, QLW_CFG1) | 0x04 | 0x03);
-
qlw_host_cmd(sc, QLW_HOST_CMD_RELEASE);
/* reset queue pointers */
@@ -1118,6 +1109,28 @@ qlw_softreset(struct qlw_softc *sc)
}
void
+qlw_dma_burst_enable(struct qlw_softc *sc)
+{
+ if (sc->sc_isp_gen == QLW_GEN_ISP1040) {
+ qlw_write(sc, QLW_CDMA_CFG,
+ qlw_read(sc, QLW_CDMA_CFG) | QLW_DMA_BURST_ENABLE);
+ qlw_write(sc, QLW_DDMA_CFG,
+ qlw_read(sc, QLW_DDMA_CFG) | QLW_DMA_BURST_ENABLE);
+ } else {
+ qlw_host_cmd(sc, QLW_HOST_CMD_PAUSE);
+ qlw_write(sc, QLW_CFG1,
+ qlw_read(sc, QLW_CFG1) | QLW_DMA_BANK);
+ qlw_write(sc, QLW_CDMA_CFG_1080,
+ qlw_read(sc, QLW_CDMA_CFG_1080) | QLW_DMA_BURST_ENABLE);
+ qlw_write(sc, QLW_DDMA_CFG_1080,
+ qlw_read(sc, QLW_DDMA_CFG_1080) | QLW_DMA_BURST_ENABLE);
+ qlw_write(sc, QLW_CFG1,
+ qlw_read(sc, QLW_CFG1) & ~QLW_DMA_BANK);
+ qlw_host_cmd(sc, QLW_HOST_CMD_RELEASE);
+ }
+}
+
+void
qlw_update(struct qlw_softc *sc, int task)
{
/* do things */
@@ -1461,6 +1474,8 @@ qlw_parse_nvram_1080(struct qlw_softc *sc, int bus)
struct qlw_nvram_bus *nv = &nvram->bus[bus];
int target;
+ sc->sc_isp_config = nvram->isp_config;
+
if (!ISSET(sc->sc_flags, QLW_FLAG_INITIATOR))
sc->sc_initiator[bus] = (nv->config1 & 0x0f);
@@ -1491,6 +1506,16 @@ qlw_init_defaults(struct qlw_softc *sc, int bus)
{
int target;
+ switch (sc->sc_isp_gen) {
+ case QLW_GEN_ISP1040:
+ sc->sc_isp_config = QLW_BURST_ENABLE | QLW_PCI_FIFO_64;
+ break;
+ case QLW_GEN_ISP1080:
+ case QLW_GEN_ISP12160:
+ sc->sc_isp_config = QLW_BURST_ENABLE | QLW_PCI_FIFO_128;
+ break;
+ }
+
sc->sc_retry_count[bus] = 0;
sc->sc_retry_delay[bus] = 0;
sc->sc_reset_delay[bus] = 3;
diff --git a/sys/dev/ic/qlwreg.h b/sys/dev/ic/qlwreg.h
index d584d7fc2d4..a84b54c11b2 100644
--- a/sys/dev/ic/qlwreg.h
+++ b/sys/dev/ic/qlwreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: qlwreg.h,v 1.1 2014/03/05 23:10:41 kettenis Exp $ */
+/* $OpenBSD: qlwreg.h,v 1.2 2014/03/08 15:13:12 kettenis Exp $ */
/*
* Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org>
@@ -35,7 +35,11 @@
#define QLW_NVRAM 0x0e
#define QLW_FLASH_BIOS_DATA 0x10
#define QLW_FLASH_BIOS_ADDR 0x12
+#define QLW_CDMA_CFG 0x20
+#define QLW_DDMA_CFG 0x40
#define QLW_MBOX_BASE 0x70
+#define QLW_CDMA_CFG_1080 0x80
+#define QLW_DDMA_CFG_1080 0xa0
#define QLW_HOST_CMD_CTRL 0xc0
#define QLW_GPIO_DATA 0xcc
#define QLW_GPIO_ENABLE 0xce
@@ -45,6 +49,15 @@
#define QLW_RESP_IN QLW_MBOX_BASE + 0xa
#define QLW_RESP_OUT QLW_MBOX_BASE + 0xa
+/* QLW_CFG1 */
+#define QLW_BURST_ENABLE 0x0004
+#define QLW_PCI_FIFO_16 0x0010
+#define QLW_PCI_FIFO_32 0x0020
+#define QLW_PCI_FIFO_64 0x0030
+#define QLW_PCI_FIFO_128 0x0040
+#define QLW_PCI_FIFO_MASK 0x0070
+#define QLW_DMA_BANK 0x0300
+
/* QLW_INT_CTRL */
#define QLW_RESET 0x0001
@@ -63,6 +76,9 @@
#define QLW_NVRAM_CLOCK 0x0001
#define QLW_NVRAM_CMD_READ 6
+/* QLW_CDMA_CFG and QLW_DDMA_CFG */
+#define QLW_DMA_BURST_ENABLE 0x0002
+
/* QLW_HOST_CMD_CTRL write */
#define QLW_HOST_CMD_SHIFT 12
#define QLW_HOST_CMD_NOP 0x0
diff --git a/sys/dev/ic/qlwvar.h b/sys/dev/ic/qlwvar.h
index 5a616f8cfe0..7ce708d6229 100644
--- a/sys/dev/ic/qlwvar.h
+++ b/sys/dev/ic/qlwvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: qlwvar.h,v 1.5 2014/03/07 22:39:07 kettenis Exp $ */
+/* $OpenBSD: qlwvar.h,v 1.6 2014/03/08 15:13:12 kettenis Exp $ */
/*
* Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org>
@@ -33,7 +33,12 @@ enum qlw_isp_gen {
};
enum qlw_isp_type {
- QLW_ISP1040 = 1,
+ QLW_ISP1020 = 1,
+ QLW_ISP1020A,
+ QLW_ISP1040,
+ QLW_ISP1040A,
+ QLW_ISP1040B,
+ QLW_ISP1040C,
QLW_ISP1240,
QLW_ISP1080,
QLW_ISP1280,
@@ -115,6 +120,8 @@ struct qlw_softc {
int sc_nvram_size;
int sc_nvram_minversion;
+ u_int16_t sc_isp_config;
+
u_int8_t sc_initiator[2];
u_int8_t sc_retry_count[2];
u_int8_t sc_retry_delay[2];
diff --git a/sys/dev/pci/qlw_pci.c b/sys/dev/pci/qlw_pci.c
index d5cbdf86b05..2adfcb5eb66 100644
--- a/sys/dev/pci/qlw_pci.c
+++ b/sys/dev/pci/qlw_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: qlw_pci.c,v 1.6 2014/03/07 22:39:08 kettenis Exp $ */
+/* $OpenBSD: qlw_pci.c,v 1.7 2014/03/08 15:13:12 kettenis Exp $ */
/*
* Copyright (c) 2011 David Gwynne <dlg@openbsd.org>
@@ -168,7 +168,27 @@ qlw_pci_attach(struct device *parent, struct device *self, void *aux)
switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_QLOGIC_ISP1020:
sc->sc_isp_gen = QLW_GEN_ISP1040;
- sc->sc_isp_type = QLW_ISP1040;
+ switch (PCI_REVISION(pa->pa_class)) {
+ case 0:
+ sc->sc_isp_type = QLW_ISP1020;
+ break;
+ case 1:
+ sc->sc_isp_type = QLW_ISP1020A;
+ break;
+ case 2:
+ sc->sc_isp_type = QLW_ISP1040;
+ break;
+ case 3:
+ sc->sc_isp_type = QLW_ISP1040A;
+ break;
+ case 4:
+ sc->sc_isp_type = QLW_ISP1040B;
+ break;
+ case 5:
+ default:
+ sc->sc_isp_type = QLW_ISP1040C;
+ break;
+ }
sc->sc_numbusses = 1;
if (PCI_REVISION(pa->pa_class) < 2)
sc->sc_clock = 40; /* ISP1020/1020A */