Date: Fri, 23 Apr 2010 17:00:23 GMT From: Alexander Motin <mav@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 177269 for review Message-ID: <201004231700.o3NH0N6C043787@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@177269?ac=10 Change 177269 by mav@mav_mavtest on 2010/04/23 16:59:30 Set some minor configuration bits. Disable/enable interrupts to acknowledge MSIs. Do some cleanup. Affected files ... .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#12 edit .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#9 edit .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_pci.c#4 edit .. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_soc.c#4 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#12 (text+ko) ==== @@ -441,9 +441,7 @@ 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; +// device_printf(dev, "EDMA mode: %d\n", mode); /* Configure new mode. */ ecfg = EDMA_CFG_RESERVED | EDMA_CFG_RESERVED2 | EDMA_CFG_EHOSTQUEUECACHEEN; if (ch->pm_present) { @@ -453,14 +451,18 @@ ch->fbs_enabled = 1; } } - ecfg |= 1 << 24; -// ecfg |= 1 << 22; - ecfg &= ~(EDMA_CFG_ESATANATVCMDQUE | EDMA_CFG_EQUE); - if (mode == MVS_EDMA_QUEUED) { + if (ch->quirks & MVS_Q_GENI) + ecfg |= EDMA_CFG_ERDBSZ; + else if (ch->quirks & MVS_Q_GENII) + ecfg |= EDMA_CFG_ERDBSZEXT | EDMA_CFG_EWRBUFFERLEN; + if (ch->quirks & MVS_Q_CT) + ecfg |= EDMA_CFG_ECUTTHROUGHEN; + if (mode != MVS_EDMA_OFF) + ecfg |= EDMA_CFG_EEARLYCOMPLETIONEN; + if (mode == MVS_EDMA_QUEUED) ecfg |= EDMA_CFG_EQUE; - } else if (mode == MVS_EDMA_NCQ) { + else if (mode == MVS_EDMA_NCQ) ecfg |= EDMA_CFG_ESATANATVCMDQUE; - } ATA_OUTL(ch->r_mem, EDMA_CFG, ecfg); mvs_setup_edma_queues(dev); /* Configure FBS */ @@ -488,12 +490,13 @@ ATA_OUTL(ch->r_mem, SATA_LTM, ltm); ATA_OUTL(ch->r_mem, EDMA_HC, hc); } - device_printf(dev, "fisc %08x\n",ATA_INL(ch->r_mem, SATA_FISC)); - device_printf(dev, "ltmode %08x\n",ATA_INL(ch->r_mem, SATA_LTM)); - device_printf(dev, "edmacfg %08x\n",ATA_INL(ch->r_mem, EDMA_CFG)); - device_printf(dev, "haltcond %08x\n",ATA_INL(ch->r_mem, EDMA_HC)); +// device_printf(dev, "fisc %08x\n",ATA_INL(ch->r_mem, SATA_FISC)); +// device_printf(dev, "ltmode %08x\n",ATA_INL(ch->r_mem, SATA_LTM)); +// device_printf(dev, "edmacfg %08x\n",ATA_INL(ch->r_mem, EDMA_CFG)); +// device_printf(dev, "haltcond %08x\n",ATA_INL(ch->r_mem, EDMA_HC)); /* Run EDMA. */ - ATA_OUTL(ch->r_mem, EDMA_CMD, EDMA_CMD_EENEDMA); + if (mode != MVS_EDMA_OFF) + ATA_OUTL(ch->r_mem, EDMA_CMD, EDMA_CMD_EENEDMA); } devclass_t mvs_devclass; @@ -746,10 +749,8 @@ status = mvs_getstatus(dev, 1); // device_printf(dev, "Legacy intr status %02x\n", // status); - if (slot->state < MVS_SLOT_RUNNING) { -// device_printf(dev, "Stray irq\n"); + if (slot->state < MVS_SLOT_RUNNING) return; - } port = ccb->ccb_h.target_id & 0x0f; /* Wait a bit for late !BUSY status update. */ if (status & ATA_S_BUSY) { @@ -776,20 +777,14 @@ ATA_INSW_STRM(ch->r_mem, ATA_DATA, (uint16_t *)(ccb->ataio.data_ptr + ch->donecount), ch->transfersize / 2); -// device_printf(dev, "After read %d status %02x\n", -// ch->transfersize, ATA_INB(ch->r_mem, ATA_ALTSTAT)); } - /* update how far we've gotten */ ch->donecount += ch->transfersize; - /* do we need a scoop more ? */ if (ccb->ataio.dxfer_len > ch->donecount) { - /* set this transfer size according to HW capabilities */ ch->transfersize = min(ccb->ataio.dxfer_len - ch->donecount, ch->curr[ccb->ccb_h.target_id].bytecount); - /* if data write command, output the data */ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { if (mvs_wait(dev, ATA_S_DRQ, ATA_S_BUSY, 1000) < 0) { @@ -800,11 +795,8 @@ ATA_OUTSW_STRM(ch->r_mem, ATA_DATA, (uint16_t *)(ccb->ataio.data_ptr + ch->donecount), ch->transfersize / 2); -// device_printf(dev, "After write %d status %02x\n", -// ch->transfersize, ATA_INB(ch->r_mem, ATA_ALTSTAT)); return; } - /* if data read command, return & wait for interrupt */ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) return; @@ -834,7 +826,6 @@ (uint16_t *)(ccb->csio.data_ptr + ch->donecount), length / 2); ch->donecount += length; - /* set next transfer size according to HW capabilities */ ch->transfersize = min(ccb->csio.dxfer_len - ch->donecount, ch->curr[ccb->ccb_h.target_id].bytecount); @@ -852,7 +843,6 @@ (uint16_t *)(ccb->csio.data_ptr + ch->donecount), length / 2); ch->donecount += length; - /* set next transfer size according to HW capabilities */ ch->transfersize = min(ccb->csio.dxfer_len - ch->donecount, ch->curr[ccb->ccb_h.target_id].bytecount); @@ -894,9 +884,6 @@ } end_finished: - mvs_tfd_read(dev, ccb); -// device_printf(dev, "After complete status %02x\n", -// ATA_INB(ch->r_mem, ATA_ALTSTAT)); mvs_end_transaction(slot, et); } @@ -1131,8 +1118,8 @@ ch->rslots |= (1 << slot->slot); ATA_OUTB(ch->r_mem, SATA_SATAICTL, port << SATA_SATAICTL_PMPTX_SHIFT); if (ccb->ccb_h.func_code == XPT_ATA_IO) { - device_printf(dev, "%d Legacy command %02x size %d\n", - port, ccb->ataio.cmd.command, ccb->ataio.dxfer_len); +// device_printf(dev, "%d Legacy command %02x size %d\n", +// port, ccb->ataio.cmd.command, ccb->ataio.dxfer_len); mvs_tfd_write(dev, ccb); /* device reset doesn't interrupt */ if (ccb->ataio.cmd.command == ATA_DEVICE_RESET) { @@ -1161,8 +1148,8 @@ ch->transfersize / 2); } } else { - device_printf(dev, "%d ATAPI command %02x size %d\n", - port, ccb->csio.cdb_io.cdb_bytes[0], ccb->csio.dxfer_len); +// device_printf(dev, "%d ATAPI command %02x size %d\n", +// port, ccb->csio.cdb_io.cdb_bytes[0], ccb->csio.dxfer_len); ch->donecount = 0; ch->transfersize = min(ccb->csio.dxfer_len, ch->curr[port].bytecount); @@ -1220,21 +1207,23 @@ return; } KASSERT(nsegs <= MVS_SG_ENTRIES, ("too many DMA segment entries\n")); - /* Get a piece of the workspace for this EPRD */ - eprd = (struct mvs_eprd *) - (ch->dma.workrq + MVS_EPRD_OFFSET + (MVS_EPRD_SIZE * slot->slot)); - /* Fill S/G table */ - for (i = 0; i < nsegs; i++) { - eprd[i].prdbal = htole32(segs[i].ds_addr); - eprd[i].bytecount = htole32(segs[i].ds_len & MVS_EPRD_MASK); - eprd[i].prdbah = htole32((segs[i].ds_addr >> 16) >> 16); - } - eprd[i - 1].bytecount |= htole32(MVS_EPRD_EOF); - if (nsegs == 1) { + /* If there is only one segment - no need to use S/G table on Gen-IIe. */ + if (nsegs == 1 && (ch->quirks & MVS_Q_GENIIE)) { slot->dma.addr = segs[0].ds_addr; slot->dma.len = segs[0].ds_len; - } else + } else { slot->dma.addr = 0; + /* Get a piece of the workspace for this EPRD */ + eprd = (struct mvs_eprd *) + (ch->dma.workrq + MVS_EPRD_OFFSET + (MVS_EPRD_SIZE * slot->slot)); + /* Fill S/G table */ + for (i = 0; i < nsegs; i++) { + eprd[i].prdbal = htole32(segs[i].ds_addr); + eprd[i].bytecount = htole32(segs[i].ds_len & MVS_EPRD_MASK); + eprd[i].prdbah = htole32((segs[i].ds_addr >> 16) >> 16); + } + eprd[i - 1].bytecount |= htole32(MVS_EPRD_EOF); + } 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)); @@ -1787,7 +1776,6 @@ int port = ccb->ccb_h.target_id & 0x0f; int i; - device_printf(dev, "Softreset command port%d\n", port); mvs_set_edma_mode(dev, MVS_EDMA_OFF); ATA_OUTB(ch->r_mem, SATA_SATAICTL, port << SATA_SATAICTL_PMPTX_SHIFT); ATA_OUTB(ch->r_mem, ATA_CONTROL, ATA_A_RESET); @@ -1985,35 +1973,6 @@ xpt_done(ccb); break; } -#if 0 - case XPT_CALC_GEOMETRY: - { - struct ccb_calc_geometry *ccg; - uint32_t size_mb; - uint32_t secs_per_cylinder; - - ccg = &ccb->ccg; - size_mb = ccg->volume_size - / ((1024L * 1024L) / ccg->block_size); - if (size_mb >= 1024 && (aha->extended_trans != 0)) { - if (size_mb >= 2048) { - ccg->heads = 255; - ccg->secs_per_track = 63; - } else { - ccg->heads = 128; - ccg->secs_per_track = 32; - } - } else { - ccg->heads = 64; - ccg->secs_per_track = 32; - } - secs_per_cylinder = ccg->heads * ccg->secs_per_track; - ccg->cylinders = ccg->volume_size / secs_per_cylinder; - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } -#endif case XPT_RESET_BUS: /* Reset the specified SCSI bus */ case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ mvs_reset(dev); ==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#9 (text+ko) ==== @@ -523,6 +523,8 @@ #define MVS_Q_GENI 1 #define MVS_Q_GENII 2 #define MVS_Q_GENIIE 4 +#define MVS_Q_SOC 8 +#define MVS_Q_CT 16 int pm_level; /* power management level */ struct mvs_slot slot[MVS_MAX_SLOTS]; @@ -573,13 +575,16 @@ 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 mtx mtx; /* MIM access lock */ + int gmim; /* Globally wanted MIM bits */ + int pmim; /* Port wanted MIM bits */ + int mim; /* Current MIM bits */ + int msi; /* MSI enabled */ + int msia; /* MSI active */ struct { void (*function)(void *); void *argument; ==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_pci.c#4 (text+ko) ==== @@ -68,9 +68,9 @@ {0x604211ab, 0x00, "Marvell 88SX6042", 4, MVS_Q_GENIIE}, {0x608011ab, 0x00, "Marvell 88SX6080", 8, MVS_Q_GENII}, {0x608111ab, 0x00, "Marvell 88SX6081", 8, MVS_Q_GENII}, - {0x704211ab, 0x00, "Marvell 88SX7042", 4, MVS_Q_GENIIE}, + {0x704211ab, 0x00, "Marvell 88SX7042", 4, MVS_Q_GENIIE|MVS_Q_CT}, {0x02419005, 0x00, "Adaptec 1420SA", 4, MVS_Q_GENII}, - {0x02439005, 0x00, "Adaptec 1430SA", 4, MVS_Q_GENIIE}, + {0x02439005, 0x00, "Adaptec 1430SA", 4, MVS_Q_GENIIE|MVS_Q_CT}, {0x00000000, 0x00, NULL, 0, 0} }; @@ -151,6 +151,7 @@ rman_fini(&ctlr->sc_iomem); return (error); } + pci_enable_busmaster(dev); mvs_ctlr_setup(dev); /* Setup interrupts. */ if (mvs_setup_interrupt(dev)) { @@ -239,7 +240,8 @@ /* Enable chip interrupts */ 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); + ctlr->mim = ctlr->gmim | ctlr->pmim; + ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->mim); /* Enable PCI interrupts */ ATA_OUTL(ctlr->r_mem, CHIP_PCIIM, 0x007fffff); return (0); @@ -259,7 +261,9 @@ ctlr->pmim |= bit; else ctlr->pmim &= ~bit; - ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->gmim | ctlr->pmim); + ctlr->mim = ctlr->gmim | ctlr->pmim; + if (!ctlr->msia) + ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->mim); mtx_unlock(&ctlr->mtx); } @@ -300,6 +304,7 @@ /* Allocate MSI if needed/present. */ if (msi && pci_alloc_msi(dev, &msi) != 0) msi = 0; + ctlr->msi = msi; /* Allocate all IRQs. */ ctlr->irq.r_irq_rid = msi ? 1 : 0; if (!(ctlr->irq.r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, @@ -332,6 +337,13 @@ ic = ATA_INL(ctlr->r_mem, CHIP_MIC); //device_printf(ctlr->dev, "irq MIC:%08x\n", ic); + if (ctlr->msi) { + mtx_lock(&ctlr->mtx); + ATA_OUTL(ctlr->r_mem, CHIP_MIM, 0); + ctlr->msia = 1; + mtx_unlock(&ctlr->mtx); + } else if (ic == 0) + return; if (ic & IC_ALL_PORTS_COAL_DONE) ATA_OUTL(ctlr->r_mem, CHIP_ICC, ~CHIP_ICC_ALL_PORTS); for (p = 0; p < ctlr->channels; p++) { @@ -364,6 +376,12 @@ } ic >>= 2; } + if (ctlr->msi) { + mtx_lock(&ctlr->mtx); + ctlr->msia = 0; + ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->mim); + mtx_unlock(&ctlr->mtx); + } } static struct resource * ==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs_soc.c#4 (text+ko) ==== @@ -59,10 +59,10 @@ int ports; int quirks; } mvs_ids[] = { - {MV_DEV_88F5182, 0x00, "Marvell 88F5182", 2, MVS_Q_GENIIE}, - {MV_DEV_88F6281, 0x00, "Marvell 88F6281", 2, MVS_Q_GENIIE}, - {MV_DEV_MV78100, 0x00, "Marvell MV78100", 2, MVS_Q_GENIIE}, - {MV_DEV_MV78100_Z0, 0x00,"Marvell MV78100", 2, MVS_Q_GENIIE}, + {MV_DEV_88F5182, 0x00, "Marvell 88F5182", 2, MVS_Q_GENIIE|MVS_Q_SOC}, + {MV_DEV_88F6281, 0x00, "Marvell 88F6281", 2, MVS_Q_GENIIE|MVS_Q_SOC}, + {MV_DEV_MV78100, 0x00, "Marvell MV78100", 2, MVS_Q_GENIIE|MVS_Q_SOC}, + {MV_DEV_MV78100_Z0, 0x00,"Marvell MV78100", 2, MVS_Q_GENIIE|MVS_Q_SOC}, {0, 0x00, NULL, 0, 0} };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004231700.o3NH0N6C043787>