diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-03-08 15:13:13 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-03-08 15:13:13 +0000 |
commit | adece212e67baf234e8993136866937f2057c999 (patch) | |
tree | afd976f8138080a150a7de5824c9c20d39735df1 /sys | |
parent | eaa89fd716ef08f5a0ce1b718a9a650eb0a254ae (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.c | 61 | ||||
-rw-r--r-- | sys/dev/ic/qlwreg.h | 18 | ||||
-rw-r--r-- | sys/dev/ic/qlwvar.h | 11 | ||||
-rw-r--r-- | sys/dev/pci/qlw_pci.c | 24 |
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 */ |