Date: Fri, 23 Apr 2010 05:12:20 GMT From: Alexander Motin <mav@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 177249 for review Message-ID: <201004230512.o3N5CKs8044791@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@177249?ac=10 Change 177249 by mav@mav_mavtest on 2010/04/23 05:12:15 Implement Command Completion Coalescing support. Affected files ... .. //depot/projects/scottl-camlock/src/sys/conf/files#73 edit .. //depot/projects/scottl-camlock/src/sys/conf/kmod.mk#22 edit .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#10 edit .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#7 edit .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_if.m#1 add .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_pci.c#2 edit .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_soc.c#2 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/conf/files#73 (text+ko) ==== @@ -1292,6 +1292,7 @@ dev/mpt/mpt_user.c optional mpt dev/msk/if_msk.c optional msk inet dev/mvs/mvs.c optional mvs +dev/mvs/mvs_if.m standard dev/mvs/mvs_pci.c optional mvs pci dev/mwl/if_mwl.c optional mwl dev/mwl/if_mwl_pci.c optional mwl pci ==== //depot/projects/scottl-camlock/src/sys/conf/kmod.mk#22 (text+ko) ==== @@ -337,7 +337,7 @@ dev/agp/agp_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \ dev/iicbus/iicbb_if.m dev/iicbus/iicbus_if.m \ dev/mmc/mmcbr_if.m dev/mmc/mmcbus_if.m \ - dev/mii/miibus_if.m dev/ofw/ofw_bus_if.m \ + dev/mii/miibus_if.m dev/mvs/mvs_if.m dev/ofw/ofw_bus_if.m \ dev/pccard/card_if.m dev/pccard/power_if.m dev/pci/pci_if.m \ dev/pci/pcib_if.m dev/ppbus/ppbus_if.m dev/smbus/smbus_if.m \ dev/sound/pcm/ac97_if.m dev/sound/pcm/channel_if.m \ ==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#10 (text+ko) ==== @@ -440,6 +440,7 @@ ch->curr_mode = mode; ch->fbs_enabled = 0; ch->fake_busy = 0; + MVS_EDMA(device_get_parent(dev), dev, mode); device_printf(dev, "EDMA mode: %d\n", mode); if (mode == MVS_EDMA_OFF) return; @@ -631,7 +632,7 @@ device_printf(dev, "FISIC %08x\n", fisic); } if (selfdis) - ch->curr_mode = MVS_EDMA_OFF; + ch->curr_mode = MVS_EDMA_UNKNOWN; ATA_OUTL(ch->r_mem, EDMA_IEC, ~iec); /* Interface errors or Device error. */ if (iec & (0xfc1e9000 | EDMA_IE_EDEVERR)) { @@ -1117,7 +1118,6 @@ void *buf; bus_size_t size; - slot->dma.nsegs = 0; slot->state = MVS_SLOT_LOADING; if (ccb->ccb_h.func_code == XPT_ATA_IO) { buf = ccb->ataio.data_ptr; @@ -1247,7 +1247,11 @@ eprd[i].prdbah = htole32((segs[i].ds_addr >> 16) >> 16); } eprd[i - 1].bytecount |= htole32(MVS_EPRD_EOF); - slot->dma.nsegs = nsegs; + if (nsegs == 1) { + slot->dma.addr = segs[0].ds_addr; + slot->dma.len = segs[0].ds_len; + } else + slot->dma.addr = 0; bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, ((slot->ccb->ccb_h.flags & CAM_DIR_IN) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); @@ -1275,14 +1279,19 @@ if (ch->quirks & MVS_Q_GENIIE) { crqb2e = (struct mvs_crqb_gen2e *) (ch->dma.workrq + MVS_CRQB_OFFSET + (MVS_CRQB_SIZE * ch->out_idx)); - crqb2e->cprdbl = htole32(eprd); - crqb2e->cprdbh = htole32((eprd >> 16) >> 16); crqb2e->ctrlflg = htole32( ((ccb->ccb_h.flags & CAM_DIR_IN) ? MVS_CRQB2E_READ : 0) | (slot->tag << MVS_CRQB2E_DTAG_SHIFT) | (port << MVS_CRQB2E_PMP_SHIFT) | (slot->slot << MVS_CRQB2E_HTAG_SHIFT)); - crqb2e->drbc = 0; + /* If there is only one segment - no need to use S/G table. */ + if (slot->dma.addr != 0) { + eprd = slot->dma.addr; + crqb2e->ctrlflg |= htole32(MVS_CRQB2E_CPRD); + crqb2e->drbc = slot->dma.len; + } + crqb2e->cprdbl = htole32(eprd); + crqb2e->cprdbh = htole32((eprd >> 16) >> 16); crqb2e->cmd[0] = 0; crqb2e->cmd[1] = 0; crqb2e->cmd[2] = ccb->ataio.cmd.command; ==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#7 (text+ko) ==== @@ -26,6 +26,8 @@ * $FreeBSD: src/sys/dev/mvs/mvs.h,v 1.11 2010/02/14 12:30:35 mav Exp $ */ +#include "mvs_if.h" + /* Chip registers */ #define CHIP_PCIEIC 0x1900 /* PCIe Interrupt Cause */ #define CHIP_PCIEIM 0x1910 /* PCIe Interrupt Mask */ @@ -40,7 +42,9 @@ #define IC_HC0 0x000001ff /* bits 0-8 = HC0 */ #define IC_HC_SHIFT 9 /* HC1 shift */ #define IC_HC1 (IC_HC0 << IC_HC_SHIFT) /* 9-17 = HC1 */ +#define IC_ERR_HC0 0x00000055 /* HC0 ERR_IRQ */ #define IC_DONE_HC0 0x000000aa /* HC0 DONE_IRQ */ +#define IC_ERR_HC1 (IC_ERR_HC0 << IC_HC_SHIFT) /* HC1 ERR_IRQ */ #define IC_DONE_HC1 (IC_DONE_HC0 << IC_HC_SHIFT) /* HC1 DONE_IRQ */ #define IC_HC0_COAL_DONE (1 << 8) /* HC0 IRQ coalescing */ #define IC_HC1_COAL_DONE (1 << 17) /* HC1 IRQ coalescing */ @@ -57,6 +61,13 @@ #define CHIP_SOC_LED 0x2C /* SoC LED Configuration */ +#define CHIP_ICC 0x18008 +#define CHIP_ICC_ALL_PORTS (1 << 4) /* all ports irq event */ +#define CHIP_ICT 0x180cc +#define CHIP_ITT 0x180d0 +#define CHIP_TRAN_COAL_CAUSE_LO 0x18088 +#define CHIP_TRAN_COAL_CAUSE_HI 0x1808c + /* Host Controller registers */ #define HC_SIZE 0x10000 #define HC_OFFSET 0x20000 @@ -448,7 +459,8 @@ struct ata_dmaslot { bus_dmamap_t data_map; /* Data DMA map */ - int nsegs; /* Number of segs loaded */ + bus_addr_t addr; /* Data address */ + uint16_t len; /* Data size */ }; /* structure holding DMA related information */ @@ -561,10 +573,13 @@ void *handle; int r_irq_rid; } irq; + struct mtx mtx; /* MIM access lock */ int quirks; int channels; int ccc; /* CCC timeout */ int cccc; /* CCC commands */ + int gmim; + int pmim; struct { void (*function)(void *); void *argument; ==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_pci.c#2 (text+ko) ==== @@ -120,8 +120,19 @@ ctlr->ccc = 0; ctlr->cccc = 0; } - if (ctlr->ccc > 100) - ctlr->ccc = 100; + if (ctlr->ccc > 100000) + ctlr->ccc = 100000; + device_printf(dev, + "Gen-%s, %d %sGbps ports, Port Multiplier %s%s\n", + ((ctlr->quirks & MVS_Q_GENI) ? "I" : + ((ctlr->quirks & MVS_Q_GENII) ? "II" : "IIe")), + ctlr->channels, + ((ctlr->quirks & MVS_Q_GENI) ? "1.5" : "3"), + ((ctlr->quirks & MVS_Q_GENI) ? + "not supported" : "supported"), + ((ctlr->quirks & MVS_Q_GENIIE) ? + " with FBS" : "")); + mtx_init(&ctlr->mtx, "MVS controller lock", NULL, MTX_DEF); /* We should have a memory BAR(0). */ ctlr->r_rid = PCIR_BAR(0); if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -147,16 +158,6 @@ rman_fini(&ctlr->sc_iomem); return ENXIO; } - device_printf(dev, - "Gen-%s, %d %sGbps ports, Port Multiplier %s%s\n", - ((ctlr->quirks & MVS_Q_GENI) ? "I" : - ((ctlr->quirks & MVS_Q_GENII) ? "II" : "IIe")), - ctlr->channels, - ((ctlr->quirks & MVS_Q_GENI) ? "1.5" : "3"), - ((ctlr->quirks & MVS_Q_GENI) ? - "not supported" : "supported"), - ((ctlr->quirks & MVS_Q_GENIIE) ? - " with FBS" : "")); /* Attach all channels on this controller */ for (unit = 0; unit < ctlr->channels; unit++) { child = device_add_child(dev, "mvsch", -1); @@ -194,6 +195,7 @@ rman_fini(&ctlr->sc_iomem); if (ctlr->r_mem) bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); + mtx_destroy(&ctlr->mtx); return (0); } @@ -201,7 +203,7 @@ mvs_ctlr_setup(device_t dev) { struct mvs_controller *ctlr = device_get_softc(dev); - int i; + int i, ccc = ctlr->ccc, cccc = ctlr->cccc, ccim = 0; /* Mask chip interrupts */ ATA_OUTL(ctlr->r_mem, CHIP_MIM, 0x00000000); @@ -209,28 +211,58 @@ ATA_OUTL(ctlr->r_mem, CHIP_PCIIM, 0x00000000); /* Clear PCI interrupts */ ATA_OUTL(ctlr->r_mem, CHIP_PCIIC, 0x00000000); - /* Clear HC interrupts */ - for (i = 0; i < ctlr->channels / 4; i++) + if (ccc && bootverbose) { + device_printf(dev, + "CCC with %dus/%dcmd enabled\n", + ctlr->ccc, ctlr->cccc); + } + ccc *= 150; + /* Configure chip-global CCC */ + if (ctlr->channels > 4 && (ctlr->quirks & MVS_Q_GENI) == 0) { + ATA_OUTL(ctlr->r_mem, CHIP_ICT, cccc); + ATA_OUTL(ctlr->r_mem, CHIP_ITT, ccc); + ATA_OUTL(ctlr->r_mem, CHIP_ICC, ~CHIP_ICC_ALL_PORTS); + if (ccc) + ccim |= IC_ALL_PORTS_COAL_DONE; + ccc = 0; + cccc = 0; + } + for (i = 0; i < ctlr->channels / 4; i++) { + /* Configure per-HC CCC */ + ATA_OUTL(ctlr->r_mem, HC_BASE(i) + HC_ICT, cccc); + ATA_OUTL(ctlr->r_mem, HC_BASE(i) + HC_ITT, ccc); + if (ccc) + ccim |= (IC_HC0_COAL_DONE << (i * IC_HC_SHIFT)); + /* Clear HC interrupts */ ATA_OUTL(ctlr->r_mem, HC_BASE(i) + HC_IC, 0x00000000); - /* Configure CCC */ -#if 0 - if (ctlr->ccc) { - ATA_OUTL(ctlr->r_mem, HC_ICT, ctlr->cccc & HC_ICT_SAICOALT_MASK); - ATA_OUTL(ctlr->r_mem, HC_ITT, (ctlr->ccc * 150000) & HC_ITT_SAITMTH_MASK); - if (bootverbose) { - device_printf(dev, - "CCC with %dms/%dcmd enabled\n", - ctlr->ccc, ctlr->cccc); - } } -#endif /* Enable chip interrupts */ - ATA_OUTL(ctlr->r_mem, CHIP_MIM, IC_HC0 | IC_HC1 /*| IC_ALL_PORTS_COAL_DONE*/); + ctlr->gmim = (ccim ? ccim : (IC_DONE_HC0 | IC_DONE_HC1)) | + IC_ERR_HC0 | IC_ERR_HC1; + ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->gmim | ctlr->pmim); /* Enable PCI interrupts */ ATA_OUTL(ctlr->r_mem, CHIP_PCIIM, 0x007fffff); return (0); } +static void +mvs_edma(device_t dev, device_t child, int mode) +{ + struct mvs_controller *ctlr = device_get_softc(dev); + int unit = ((struct mvs_channel *)device_get_softc(child))->unit; + int bit = IC_DONE_IRQ << (unit * 2 + unit / 4) ; + + if (ctlr->ccc == 0) + return; + mtx_lock(&ctlr->mtx); + if (mode == MVS_EDMA_OFF) + ctlr->pmim |= bit; + else + ctlr->pmim &= ~bit; + ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->gmim | ctlr->pmim); + mtx_unlock(&ctlr->mtx); +} + static int mvs_suspend(device_t dev) { @@ -301,10 +333,10 @@ ic = ATA_INL(ctlr->r_mem, CHIP_MIC); //device_printf(ctlr->dev, "irq MIC:%08x\n", ic); if (ic & IC_ALL_PORTS_COAL_DONE) - ATA_OUTL(ctlr->r_mem, CHIP_MIC, ~IC_ALL_PORTS_COAL_DONE); + ATA_OUTL(ctlr->r_mem, CHIP_ICC, ~CHIP_ICC_ALL_PORTS); for (p = 0; p < ctlr->channels; p++) { if ((p & 3) == 0) { - if (p == 4) + if (p != 0) ic >>= 1; if ((ic & IC_HC0) == 0) { p += 3; @@ -438,6 +470,7 @@ DEVMETHOD(bus_release_resource, mvs_release_resource), DEVMETHOD(bus_setup_intr, mvs_setup_intr), DEVMETHOD(bus_teardown_intr,mvs_teardown_intr), + DEVMETHOD(mvs_edma, mvs_edma), { 0, 0 } }; static driver_t mvs_driver = { ==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_soc.c#2 (text+ko) ==== @@ -112,8 +112,19 @@ ctlr->ccc = 0; ctlr->cccc = 0; } - if (ctlr->ccc > 100) - ctlr->ccc = 100; + if (ctlr->ccc > 100000) + ctlr->ccc = 100000; + device_printf(dev, + "Gen-%s, %d %sGbps ports, Port Multiplier %s%s\n", + ((ctlr->quirks & MVS_Q_GENI) ? "I" : + ((ctlr->quirks & MVS_Q_GENII) ? "II" : "IIe")), + ctlr->channels, + ((ctlr->quirks & MVS_Q_GENI) ? "1.5" : "3"), + ((ctlr->quirks & MVS_Q_GENI) ? + "not supported" : "supported"), + ((ctlr->quirks & MVS_Q_GENIIE) ? + " with FBS" : "")); + mtx_init(&ctlr->mtx, "MVS controller lock", NULL, MTX_DEF); /* We should have a memory BAR(0). */ ctlr->r_rid = 0; if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -139,16 +150,6 @@ rman_fini(&ctlr->sc_iomem); return ENXIO; } - device_printf(dev, - "Gen-%s, %d %sGbps ports, Port Multiplier %s%s\n", - ((ctlr->quirks & MVS_Q_GENI) ? "I" : - ((ctlr->quirks & MVS_Q_GENII) ? "II" : "IIe")), - ctlr->channels, - ((ctlr->quirks & MVS_Q_GENI) ? "1.5" : "3"), - ((ctlr->quirks & MVS_Q_GENI) ? - "not supported" : "supported"), - ((ctlr->quirks & MVS_Q_GENIIE) ? - " with FBS" : "")); /* Attach all channels on this controller */ for (unit = 0; unit < ctlr->channels; unit++) { child = device_add_child(dev, "mvsch", -1); @@ -185,6 +186,7 @@ rman_fini(&ctlr->sc_iomem); if (ctlr->r_mem) bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); + mtx_destroy(&ctlr->mtx); return (0); } @@ -192,6 +194,7 @@ mvs_ctlr_setup(device_t dev) { struct mvs_controller *ctlr = device_get_softc(dev); + int ccc = ctlr->ccc, cccc = ctlr->cccc, ccim = 0; /* Mask chip interrupts */ ATA_OUTL(ctlr->r_mem, CHIP_SOC_MIM, 0x00000000); @@ -199,23 +202,41 @@ ATA_OUTL(ctlr->r_mem, HC_IC, 0x00000000); /* Clear chip interrupts */ ATA_OUTL(ctlr->r_mem, CHIP_SOC_MIC, 0); - /* Configure CCC */ -#if 0 - if (ctlr->ccc) { - ATA_OUTL(ctlr->r_mem, HC_ICT, ctlr->cccc & HC_ICT_SAICOALT_MASK); - ATA_OUTL(ctlr->r_mem, HC_ITT, (ctlr->ccc * 150000) & HC_ITT_SAITMTH_MASK); - if (bootverbose) { - device_printf(dev, - "CCC with %dms/%dcmd enabled\n", - ctlr->ccc, ctlr->cccc); - } + /* Configure per-HC CCC */ + if (ccc && bootverbose) { + device_printf(dev, + "CCC with %dus/%dcmd enabled\n", + ctlr->ccc, ctlr->cccc); } -#endif + ccc *= 150; + ATA_OUTL(ctlr->r_mem, HC_ICT, cccc); + ATA_OUTL(ctlr->r_mem, HC_ITT, ccc); + if (ccc) + ccim |= IC_HC0_COAL_DONE; /* Enable chip interrupts */ - ATA_OUTL(ctlr->r_mem, CHIP_SOC_MIM, IC_HC0 | IC_HC1 /*| IC_ALL_PORTS_COAL_DONE*/); + ctlr->gmim = (ccc ? IC_HC0_COAL_DONE : IC_DONE_HC0) | IC_ERR_HC0; + ATA_OUTL(ctlr->r_mem, CHIP_SOC_MIM, ctlr->gmim | ctlr->pmim); return (0); } +static void +mvs_edma(device_t dev, device_t child, int mode) +{ + struct mvs_controller *ctlr = device_get_softc(dev); + int unit = ((struct mvs_channel *)device_get_softc(child))->unit; + int bit = IC_DONE_IRQ << (unit * 2); + + if (ctlr->ccc == 0) + return; + mtx_lock(&ctlr->mtx); + if (mode == MVS_EDMA_OFF) + ctlr->pmim |= bit; + else + ctlr->pmim &= ~bit; + ATA_OUTL(ctlr->r_mem, CHIP_SOC_MIM, ctlr->gmim | ctlr->pmim); + mtx_unlock(&ctlr->mtx); +} + static int mvs_suspend(device_t dev) { @@ -272,30 +293,21 @@ ic = ATA_INL(ctlr->r_mem, CHIP_SOC_MIC); //device_printf(ctlr->dev, "irq MIC:%08x\n", ic); - if (ic & IC_ALL_PORTS_COAL_DONE) - ATA_OUTL(ctlr->r_mem, CHIP_SOC_MIC, ~IC_ALL_PORTS_COAL_DONE); + if ((ic & IC_HC0) == 0) + return; + aic = 0; + if (ic & (IC_DONE_IRQ << 0)) + aic |= HC_IC_DONE(0) | HC_IC_DEV(0); + if (ic & (IC_DONE_IRQ << 2)) + aic |= HC_IC_DONE(1) | HC_IC_DEV(1); + if (ic & (IC_DONE_IRQ << 4)) + aic |= HC_IC_DONE(2) | HC_IC_DEV(2); + if (ic & (IC_DONE_IRQ << 6)) + aic |= HC_IC_DONE(3) | HC_IC_DEV(3); + if (ic & IC_HC0_COAL_DONE) + aic |= HC_IC_COAL; + ATA_OUTL(ctlr->r_mem, HC_IC, ~aic); for (p = 0; p < ctlr->channels; p++) { - if ((p & 3) == 0) { - if (p == 4) - ic >>= 1; - if ((ic & IC_HC0) == 0) { - p += 3; - ic >>= 8; - continue; - } - aic = 0; - if (ic & (IC_DONE_IRQ << 0)) - aic |= HC_IC_DONE(0) | HC_IC_DEV(0); - if (ic & (IC_DONE_IRQ << 2)) - aic |= HC_IC_DONE(1) | HC_IC_DEV(1); - if (ic & (IC_DONE_IRQ << 4)) - aic |= HC_IC_DONE(2) | HC_IC_DEV(2); - if (ic & (IC_DONE_IRQ << 6)) - aic |= HC_IC_DONE(3) | HC_IC_DEV(3); - if (ic & IC_HC0_COAL_DONE) - aic |= HC_IC_COAL; - ATA_OUTL(ctlr->r_mem, HC_IC, ~aic); - } arg.cause = ic & (IC_ERR_IRQ|IC_DONE_IRQ); if ((arg.cause != 0) && (function = ctlr->interrupt[p].function)) { @@ -410,6 +422,7 @@ DEVMETHOD(bus_release_resource, mvs_release_resource), DEVMETHOD(bus_setup_intr, mvs_setup_intr), DEVMETHOD(bus_teardown_intr,mvs_teardown_intr), + DEVMETHOD(mvs_edma, mvs_edma), { 0, 0 } }; static driver_t mvs_driver = {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004230512.o3N5CKs8044791>