Esempio n. 1
0
void
dmac3_attach(device_t parent, device_t self, void *aux)
{
	struct dmac3_softc *sc = device_private(self);
	struct apbus_attach_args *apa = aux;
	struct dmac3reg *reg;
	static paddr_t dmamap = DMAC3_PAGEMAP;
	static vaddr_t dmaaddr = 0;

	sc->sc_dev = self;
	reg = (void *)apa->apa_hwbase;
	sc->sc_reg = reg;
	sc->sc_ctlnum = apa->apa_ctlnum;
	sc->sc_dmamap = (uint32_t *)dmamap;
	sc->sc_dmaaddr = dmaaddr;
	dmamap += 0x1000;
	dmaaddr += 0x200000;

	sc->sc_conf = DMAC3_CONF_PCEN | DMAC3_CONF_DCEN | DMAC3_CONF_FASTACCESS;

	dmac3_reset(sc);

	aprint_normal(" slot%d addr 0x%lx", apa->apa_slotno, apa->apa_hwbase);
	aprint_normal(": ctlnum = %d, map = %p, va = %lx",
	       apa->apa_ctlnum, sc->sc_dmamap, sc->sc_dmaaddr);
	aprint_normal("\n");
}
Esempio n. 2
0
void
dmac3_start(struct dmac3_softc *sc, vaddr_t addr, int len, int direction)
{
	struct dmac3reg *reg = sc->sc_reg;
	paddr_t pa;
	vaddr_t start, end, v;
	volatile uint32_t *p;

	if (reg->csr & DMAC3_CSR_ENABLE)
		dmac3_reset(sc);

	start = mips_trunc_page(addr);
	end   = mips_round_page(addr + len);
	p = sc->sc_dmamap;
	for (v = start; v < end; v += PAGE_SIZE) {
		pa = kvtophys(v);
		mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(pa), PAGE_SIZE);
		*p++ = 0;
		*p++ = (pa >> PGSHIFT) | 0xc0000000;
	}
	*p++ = 0;
	*p++ = 0x003fffff;

	addr &= PGOFSET;
	addr += sc->sc_dmaaddr;

	reg->len = len;
	reg->addr = addr;
	reg->intr = DMAC3_INTR_EOPIE | DMAC3_INTR_INTEN;
	reg->csr = DMAC3_CSR_ENABLE | direction | BURST_MODE | APAD_MODE;
}
Esempio n. 3
0
int
dmac3_intr(void *v)
{
	struct dmac3_softc *sc = v;
	struct dmac3reg *reg = sc->sc_reg;
	int intr, conf, rv = 1;

	intr = reg->intr;
	if ((intr & DMAC3_INTR_INT) == 0)
		return 0;

	/* clear interrupt */
	conf = reg->conf;
	reg->conf = conf;
	reg->intr = intr;

	if (intr & DMAC3_INTR_PERR) {
		printf("%s: intr = 0x%x\n", device_xname(sc->sc_dev), intr);
		rv = -1;
	}

	if (conf & (DMAC3_CONF_IPER | DMAC3_CONF_MPER | DMAC3_CONF_DERR)) {
		printf("%s: conf = 0x%x\n", device_xname(sc->sc_dev), conf);
		if (conf & DMAC3_CONF_DERR) {
			printf("DMA address = 0x%x\n", reg->addr);
			printf("resetting DMA...\n");
			dmac3_reset(sc);
		}
	}

	return rv;
}
Esempio n. 4
0
void
spifi_attach(device_t parent, device_t self, void *aux)
{
	struct spifi_softc *sc = device_private(self);
	struct apbus_attach_args *apa = aux;
	struct dmac3_softc *dma;
	int intr, i;

	sc->sc_dev = self;

	/* Initialize scbs. */
	TAILQ_INIT(&sc->free_scb);
	TAILQ_INIT(&sc->ready_scb);
	for (i = 0; i < __arraycount(sc->sc_scb); i++)
		TAILQ_INSERT_TAIL(&sc->free_scb, &sc->sc_scb[i], chain);

	sc->sc_reg = (struct spifi_reg *)apa->apa_hwbase;
	sc->sc_id = 7;					/* XXX */

	/* Find my dmac3. */
	dma = dmac3_link(apa->apa_ctlnum);
	if (dma == NULL) {
		aprint_error(": cannot find slave dmac\n");
		return;
	}
	sc->sc_dma = dma;

	aprint_normal(" slot%d addr 0x%lx", apa->apa_slotno, apa->apa_hwbase);
	aprint_normal(": SCSI ID = %d, using %s\n",
	    sc->sc_id, device_xname(dma->sc_dev));

	dmac3_reset(sc->sc_dma);

	DMAC3_SLOWACCESS(sc);
	spifi_reset(sc);
	DMAC3_FASTACCESS(sc);

	sc->sc_adapter.adapt_dev = self;
	sc->sc_adapter.adapt_nchannels = 1;
	sc->sc_adapter.adapt_openings = 7;
	sc->sc_adapter.adapt_max_periph = 1;
	sc->sc_adapter.adapt_ioctl = NULL;
	sc->sc_adapter.adapt_minphys = minphys;
	sc->sc_adapter.adapt_request = spifi_scsipi_request;

	memset(&sc->sc_channel, 0, sizeof(sc->sc_channel));
	sc->sc_channel.chan_adapter = &sc->sc_adapter;
	sc->sc_channel.chan_bustype = &scsi_bustype;
	sc->sc_channel.chan_channel = 0;
	sc->sc_channel.chan_ntargets = 8;
	sc->sc_channel.chan_nluns = 8;
	sc->sc_channel.chan_id = sc->sc_id;

	if (apa->apa_slotno == 0)
		intr = NEWS5000_INT0_DMAC;
	else
		intr = SLOTTOMASK(apa->apa_slotno);
	apbus_intr_establish(0, intr, 0, spifi_intr, sc, apa->apa_name,
	    apa->apa_ctlnum);

	config_found(self, &sc->sc_channel, scsiprint);
}