Exemplo n.º 1
0
static void
uninorth_conf_write_v3(void *cookie, pcitag_t tag, int reg, pcireg_t data)
{
	pci_chipset_tag_t pc = cookie;
	int32_t *daddr = pc->pc_data;
	int bus, dev, func, s;
	uint32_t x;

	if ((unsigned int)reg >= PCI_CONF_SIZE)
		return;

	/* UniNorth seems to have a 64bit data port */
	if (reg & 0x04)
		daddr++;

	pci_decompose_tag(pc, tag, &bus, &dev, &func);

	x = (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 1;
	/* Set extended register bits */
	x |= (reg >> 8) << 28;

	s = splhigh();

	out32rb(pc->pc_addr, x);
	in32rb(pc->pc_addr);
	out32rb(daddr, data);
	out32rb(pc->pc_addr, 0);
	in32rb(pc->pc_addr);

	splx(s);
}
Exemplo n.º 2
0
static status_t
grackle_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function,
	uint8 offset, uint8 size, uint32 *value)
{
	grackle_host_bridge *bridge = (grackle_host_bridge*)cookie;
	TRACE("grackle_read_pci_config(bus=%u, dev=%u, func=%u, offset=%u, "
		"size=%u)\n", (int)bus, (int)device, (int)function, (int)offset,
		(int)size);

	out32rb(bridge->address_registers, (1 << 31)
		| (bus << 16) | ((device & 0x1f) << 11) | ((function & 0x7) << 8)
		| (offset & 0xfc));

	addr_t dataAddress = bridge->data_registers + (offset & 0x3);
	switch (size) {
		case 1:
			*value = in8rb(dataAddress);
			break;
		case 2:
			*value = in16rb(dataAddress);
			break;
		case 4:
			*value = in32rb(dataAddress);
			break;
		default:
			*value = 0xffffffff;
			break;
	}

	out32rb(bridge->address_registers, 0);

	return B_OK;
}
Exemplo n.º 3
0
hide void
mc_reset_txdma(struct mc_softc *sc)
{
	dbdma_command_t *cmd = sc->sc_txdmacmd;
	dbdma_regmap_t *dmareg = sc->sc_txdma;
	u_int8_t maccc;

	/* disable transmitter */
	maccc = NIC_GET(sc, MACE_MACCC);
	NIC_PUT(sc, MACE_MACCC, maccc & ~ENXMT);

	dbdma_reset(dmareg);

	DBDMA_BUILD(cmd, DBDMA_CMD_OUT_LAST, 0, 0, sc->sc_txbuf_phys,
		DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
	cmd++;
	DBDMA_BUILD(cmd, DBDMA_CMD_STOP, 0, 0, 0,
		DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);

	out32rb(&dmareg->d_cmdptrhi, 0);
	out32rb(&dmareg->d_cmdptrlo, kvtop((void *)sc->sc_txdmacmd));

	/* restore old value */
	NIC_PUT(sc, MACE_MACCC, maccc);
}
Exemplo n.º 4
0
/*
 * Reset and enable bmac by heathrow FCR.
 */
void
bmac_reset_chip(struct bmac_softc *sc)
{
	u_int v;

	dbdma_reset(sc->sc_txdma);
	dbdma_reset(sc->sc_rxdma);

	v = in32rb(heathrow_FCR);

	v |= EnetEnable;
	out32rb(heathrow_FCR, v);
	delay(50000);

	/* assert reset */
	v |= ResetEnetCell;
	out32rb(heathrow_FCR, v);
	delay(50000);

	/* deassert reset */
	v &= ~ResetEnetCell;
	out32rb(heathrow_FCR, v);
	delay(50000);

	/* enable */
	v |= EnetEnable;
	out32rb(heathrow_FCR, v);
	delay(50000);

	/* make certain they stay set? */
	out32rb(heathrow_FCR, v);
	v = in32rb(heathrow_FCR);
}
Exemplo n.º 5
0
void
ibmnws_pci_indirect_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
{
	int s;

	s = splhigh();
	out32rb(PCI_MODE1_ADDRESS_REG, tag | reg);
	out32rb(PCI_MODE1_DATA_REG, data);
	out32rb(PCI_MODE1_ADDRESS_REG, 0);
	splx(s);
}
Exemplo n.º 6
0
void
pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{

	if ((unsigned int)reg >= PCI_CONF_SIZE)
		return;

	out32rb(SANDPOINT_PCI_CONFIG_ADDR, tag | reg);
	out32rb(SANDPOINT_PCI_CONFIG_DATA, data);
	out32rb(SANDPOINT_PCI_CONFIG_ADDR, 0);
}
Exemplo n.º 7
0
/*
 * The Kahlua documentation says that "reg" should be left-shifted by two
 * and be in bits 2-7.  Apparently not.  It doesn't work that way, and the
 * DINK32 ROM doesn't do it that way (I peeked at 0xfec00000 after running
 * the DINK32 "pcf" command).
 */
pcireg_t
pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
	pcireg_t data;

	if ((unsigned int)reg >= PCI_CONF_SIZE)
		return (pcireg_t) -1;

	out32rb(SANDPOINT_PCI_CONFIG_ADDR, tag | reg);
	data = in32rb(SANDPOINT_PCI_CONFIG_DATA);
	out32rb(SANDPOINT_PCI_CONFIG_ADDR, 0);
	return data;
}
Exemplo n.º 8
0
static void
grackle_conf_write(void *cookie, pcitag_t tag, int reg, pcireg_t data)
{
	pci_chipset_tag_t pc = cookie;
	int s;

	s = splhigh();

	out32rb(pc->pc_addr, tag | reg);
	out32rb(pc->pc_data, data);
	out32rb(pc->pc_addr, 0);

	splx(s);
}
Exemplo n.º 9
0
pcireg_t
ibmnws_pci_indirect_conf_read(void *v, pcitag_t tag, int reg)
{
	pcireg_t data;
	int s;

	s = splhigh();
	out32rb(PCI_MODE1_ADDRESS_REG, tag | reg);
	data = in32rb(PCI_MODE1_DATA_REG);
	out32rb(PCI_MODE1_ADDRESS_REG, 0);
	splx(s);

	return data;
}
Exemplo n.º 10
0
void
macobio_modem_power(int enable)
{
	u_int32_t val;
	struct macobio_softc *sc = macobio_cd.cd_devs[0];
	if (PCI_PRODUCT(sc->sc_id) == PCI_PRODUCT_APPLE_KEYLARGO ||
	    PCI_PRODUCT(sc->sc_id) == PCI_PRODUCT_APPLE_INTREPID) {
		val = in32rb(sc->obiomem + 0x40);
		if (enable)
			val = val & ~((u_int32_t)1<<25);
		else 
			val = val | ((u_int32_t)1<<25);
		out32rb(sc->obiomem + 0x40, val);
	}
	if (PCI_PRODUCT(sc->sc_id) == PCI_PRODUCT_APPLE_PANGEA_MACIO) {
		if (enable) {
			/* set reset */
			out8(sc->obiomem + 0x006a + 0x03, 0x04);
			/* power modem on */
			out8(sc->obiomem + 0x006a + 0x02, 0x04);
			/* unset reset */
			out8(sc->obiomem + 0x006a + 0x03, 0x05);
		}  else {
			/* disable it how? */
		}
	}
}
Exemplo n.º 11
0
static int
uninorth_enable_config(struct uninorth_softc *sc, u_int bus, u_int slot,
    u_int func, u_int reg)
{
	u_int32_t	cfgval;

	if (sc->sc_bus == bus) {
		/*
		 * No slots less than 11 on the primary bus
		 */
		if (slot < 11)
			return (0);

		cfgval = (1 << slot) | (func << 8) | (reg & 0xfc);
	} else {
		cfgval = (bus << 16) | (slot << 11) | (func << 8) |
		    (reg & 0xfc) | 1;
	}
        
	do {
		out32rb(sc->sc_addr, cfgval);
	} while (in32rb(sc->sc_addr) != cfgval);

	return (1);
}
Exemplo n.º 12
0
void
prep_pci_direct_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
{
	int bus, device, function;
	int s;

	DPRINTF(("prep_pci_direct_conf_write(0x%lx, 0x%x, 0x%02x, 0x%08lx) ",
	    (unsigned long)v, tag, reg, (unsigned long)data));

	prep_pci_direct_decompose_tag(v, tag, &bus, &device, &function);

	if (bus == 0) {
		/* Check if device selector is within selector range. */
		if (1 << device & ~PCI_DCONF_DEV) {
			/* Should never happen. */
			panic("prep_pci_direct_conf_write: bad device %d",
			    device);
		}
		tag = (1 << device) | (function << PCI_DCONF_FUNC_SHIFT);
	}

	s = splhigh();
	out32rb(PCI_DCONF_BASE | tag | reg, data);
	splx(s);
}
Exemplo n.º 13
0
hide void
mc_reset_rxdma(struct mc_softc *sc)
{
	dbdma_command_t *cmd = sc->sc_rxdmacmd;
	dbdma_regmap_t *dmareg = sc->sc_rxdma;
	int i;
	u_int8_t maccc;

	/* Disable receiver, reset the DMA channels */
	maccc = NIC_GET(sc, MACE_MACCC);
	NIC_PUT(sc, MACE_MACCC, maccc & ~ENRCV);

	dbdma_reset(dmareg);

	for (i = 0; i < MC_RXDMABUFS; i++) {
		DBDMA_BUILD(cmd, DBDMA_CMD_IN_LAST, 0, ETHERMTU + 22,
			sc->sc_rxbuf_phys + MC_BUFSIZE * i, DBDMA_INT_ALWAYS,
			DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
		cmd++;
	}

	DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0,
		DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS);
	out32rb(&cmd->d_cmddep, kvtop((void *)sc->sc_rxdmacmd));
	cmd++;

	dbdma_start(dmareg, sc->sc_rxdmacmd);

	sc->sc_tail = 0;

	/* Reenable receiver, reenable DMA */
	NIC_PUT(sc, MACE_MACCC, maccc);
}
Exemplo n.º 14
0
static void
grackle_write_config(device_t dev, u_int bus, u_int slot, u_int func,
    u_int reg, u_int32_t val, int width)
{
	struct		grackle_softc *sc;
	vm_offset_t	caoff;

	sc = device_get_softc(dev);
	caoff = sc->sc_data + (reg & 0x03);

	if (grackle_enable_config(sc, bus, slot, func, reg)) {
		switch (width) {
		case 1:
			out8rb(caoff, val);
			(void)in8rb(caoff);
			break;
		case 2:
			out16rb(caoff, val);
			(void)in16rb(caoff);
			break;
		case 4:
			out32rb(caoff, val);
			(void)in32rb(caoff);
			break;
		}
	}
	grackle_disable_config(sc);
}
Exemplo n.º 15
0
static void
grackle_conf_write(void *cookie, pcitag_t tag, int reg, pcireg_t data)
{
	pci_chipset_tag_t pc = cookie;
	int s;

	if ((unsigned int)reg >= PCI_CONF_SIZE)
		return;

	s = splhigh();

	out32rb(pc->pc_addr, tag | reg);
	out32rb(pc->pc_data, data);
	out32rb(pc->pc_addr, 0);

	splx(s);
}
Exemplo n.º 16
0
void
pchbattach(struct device *parent, struct device *self, void *aux)
{
	struct pci_attach_args *pa = aux;
	char devinfo[256];
#if NAGP > 0
	struct agpbus_attach_args apa;
#endif
	volatile unsigned char *python;
	uint32_t v;
	
	aprint_normal("\n");

	/*
	 * All we do is print out a description.  Eventually, we
	 * might want to add code that does something that's
	 * possibly chipset-specific.
	 */

	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	aprint_normal("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo,
	    PCI_REVISION(pa->pa_class));

	switch (PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_IBM:
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_IBM_82660:
			ibm82660_print(pa, self);
			break;
		case PCI_PRODUCT_IBM_PYTHON:
			python = mapiodev(0xfeff6000, 0x60);
			v = 0x88b78e01; /* taken from linux */
			out32rb(python+0x30, v);
			v = in32rb(python+0x30);
			aprint_debug("Reset python reg 30 to 0x%x\n", v);
			break;
		}
		break;
	case PCI_VENDOR_MOT:
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_MOT_MPC105:
			mpc105_print(pa, self);
			break;
		case PCI_PRODUCT_MOT_MPC106:
			mpc106_print(pa, self);
			break;
		}
		break;
	}

#if NAGP > 0
	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
			       NULL, NULL) != 0) {
		apa.apa_pci_args = *pa;
		config_found_ia(self, "agpbus", &apa, agpbusprint);
	}
#endif /* NAGP */
}
Exemplo n.º 17
0
static pcireg_t
uninorth_conf_read(void *cookie, pcitag_t tag, int reg)
{
	pci_chipset_tag_t pc = cookie;
	int32_t *daddr = pc->pc_data;
	pcireg_t data;
	int bus, dev, func, s;
	uint32_t x;

	if ((unsigned int)reg >= PCI_CONF_SIZE)
		return (pcireg_t) -1;

	/* UniNorth seems to have a 64bit data port */
	if (reg & 0x04)
		daddr++;

	pci_decompose_tag(pc, tag, &bus, &dev, &func);

	/*
	 * bandit's minimum device number of the first bus is 11.
	 * So we behave as if there is no device when dev < 11.
	 */
	if (func > 7)
		panic("pci_conf_read: func > 7");

	if (bus == pc->pc_bus) {
		if (dev < 11)
			return 0xffffffff;
		x = (1 << dev) | (func << 8) | reg;
	} else
		x = tag | reg | 1;

	s = splhigh();

	out32rb(pc->pc_addr, x);
	in32rb(pc->pc_addr);
	data = 0xffffffff;
	if (!badaddr(daddr, 4))
		data = in32rb(daddr);
	out32rb(pc->pc_addr, 0);
	in32rb(pc->pc_addr);
	splx(s);

	return data;
}
Exemplo n.º 18
0
/* set interrupt priority and destination */
static void
iocc_set_priority(int cpu, int pri, int irq)
{
        uint32_t x;

        x = pri;
        x |= cpu<<8;
        out32rb(RS6000_BUS_SPACE_IO + IOCC_XIVR(irq), x);
}
Exemplo n.º 19
0
/* disable an IRQ on the IOCC */
static void
iocc_disable_irq(struct pic_ops *pic, int irq)
{
        uint32_t mask;

        mask = in32rb(RS6000_BUS_SPACE_IO + IOCC_IEE);
        mask &= ~(1 << irq);
        out32rb(RS6000_BUS_SPACE_IO + IOCC_IEE, mask);
}
Exemplo n.º 20
0
/* enable an IRQ on the IOCC */
static void
iocc_enable_irq(struct pic_ops *pic, int irq, int type)
{
        uint32_t mask;

        mask = in32rb(RS6000_BUS_SPACE_IO + IOCC_IEE);
        mask |= 1 << irq;
        out32rb(RS6000_BUS_SPACE_IO + IOCC_IEE, mask);
}
Exemplo n.º 21
0
static void
grackle_disable_config(struct grackle_softc *sc)
{
	/*
	 * Clear the GRACKLE_CFG_ENABLE bit to prevent stray
	 * accesses from causing config cycles
	 */
	out32rb(sc->sc_addr, 0);
}
Exemplo n.º 22
0
void
macobio_disable(int offset, u_int32_t bits)
{
	struct macobio_softc *sc = macobio_cd.cd_devs[0];
	if (sc->obiomem == 0)
		return;

	bits =  in32rb(sc->obiomem + offset) & ~bits;
	out32rb(sc->obiomem + offset, bits);
}
Exemplo n.º 23
0
void
keylargo_fcr_enable(int offset, u_int32_t bits)
{
	struct macobio_softc *sc = macobio_cd.cd_devs[0];
	if (sc->obiomem == 0)
		return;

	bits |=  in32rb(sc->obiomem + offset);
	out32rb(sc->obiomem + offset, bits);
}
Exemplo n.º 24
0
static pcireg_t
grackle_conf_read(void *cookie, pcitag_t tag, int reg)
{
	pci_chipset_tag_t pc = cookie;
	pcireg_t data;
	int s;

	s = splhigh();

	out32rb(pc->pc_addr, tag | reg);
	data = 0xffffffff;
	if (!badaddr(pc->pc_data, 4))
		data = in32rb(pc->pc_data);
	out32rb(pc->pc_addr, 0);

	splx(s);

	return data;
}
Exemplo n.º 25
0
static void
uninorth_conf_write(void *cookie, pcitag_t tag, int reg, pcireg_t data)
{
	pci_chipset_tag_t pc = cookie;
	int32_t *daddr = pc->pc_data;
	int bus, dev, func, s;
	uint32_t x;

	if ((unsigned int)reg >= PCI_CONF_SIZE)
		return;

	/* UniNorth seems to have a 64bit data port */
	if (reg & 0x04)
		daddr++;

	pci_decompose_tag(pc, tag, &bus, &dev, &func);

	if (func > 7)
		panic("pci_conf_write: func > 7");

	if (bus == pc->pc_bus) {
		if (dev < 11)
			panic("pci_conf_write: dev < 11");
		x = (1 << dev) | (func << 8) | reg;
	} else
		x = tag | reg | 1;

	s = splhigh();

	out32rb(pc->pc_addr, x);
	in32rb(pc->pc_addr);
	out32rb(daddr, data);
	out32rb(pc->pc_addr, 0);
	in32rb(pc->pc_addr);

	splx(s);
}
Exemplo n.º 26
0
static int
grackle_enable_config(struct grackle_softc *sc, u_int bus, u_int slot,
    u_int func, u_int reg)
{
	u_int32_t	cfgval;

	/*
	 * Unlike UniNorth, the format of the config word is the same
	 * for local (0) and remote busses.
	 */
	cfgval = (bus << 16) | (slot << 11) | (func << 8) | (reg & 0xFC)
	    | GRACKLE_CFG_ENABLE;

	out32rb(sc->sc_addr, cfgval);
	(void) in32rb(sc->sc_addr);

	return (1);
}
Exemplo n.º 27
0
static int
uninorth_enable_config(struct uninorth_softc *sc, u_int bus, u_int slot,
    u_int func, u_int reg)
{
	uint32_t	cfgval;
	uint32_t	pass;

	if (resource_int_value(device_get_name(sc->pci_sc.sc_dev),
	        device_get_unit(sc->pci_sc.sc_dev), "skipslot", &pass) == 0) {
		if (pass == slot)
			return (0);
	}

	/*
	 * Issue type 0 configuration space accesses for the root bus.
	 *
	 * NOTE: On U4, issue only type 1 accesses. There is a secret
	 * PCI Express <-> PCI Express bridge not present in the device tree,
	 * and we need to route all of our configuration space through it.
	 */
	if (sc->pci_sc.sc_bus == bus && sc->sc_ver < 4) {
		/*
		 * No slots less than 11 on the primary bus on U3 and lower
		 */
		if (slot < 11)
			return (0);

		cfgval = (1 << slot) | (func << 8) | (reg & 0xfc);
	} else {
		cfgval = (bus << 16) | (slot << 11) | (func << 8) |
		    (reg & 0xfc) | 1;
	}

	/* Set extended register bits on U4 */
	if (sc->sc_ver == 4)
		cfgval |= (reg >> 8) << 28;

	do {
		out32rb(sc->sc_addr, cfgval);
	} while (in32rb(sc->sc_addr) != cfgval);

	return (1);
}
Exemplo n.º 28
0
static void
uninorth_write_config(device_t dev, u_int bus, u_int slot, u_int func,
    u_int reg, u_int32_t val, int width)
{
	struct		uninorth_softc *sc;
	vm_offset_t	caoff;

	sc = device_get_softc(dev);
	caoff = sc->sc_data + (reg & 0x07);

	if (uninorth_enable_config(sc, bus, slot, func, reg)) {
		switch (width) {
		case 1:
			out8rb(caoff, val);
			break;
		case 2:
			out16rb(caoff, val);
			break;
		case 4:
			out32rb(caoff, val);
			break;
		}
	}
}
Exemplo n.º 29
0
/* Issue an EOI to the IOCC */
static void
iocc_ack_irq(struct pic_ops *pic, int irq)
{
        out32rb(RS6000_BUS_SPACE_IO + IOCC_EOI(irq), 0x1); /* val is ignored */
}
Exemplo n.º 30
0
void
xlights_attach(struct device *parent, struct device *self, void *aux)
{
	struct xlights_softc *sc = (struct xlights_softc *)self;
	struct confargs *ca = aux;
	int nseg, error, intr[6];
	u_int32_t reg[4];
	int type;

	sc->sc_node = OF_child(ca->ca_node);

	OF_getprop(sc->sc_node, "reg", reg, sizeof(reg));
	ca->ca_reg[0] += ca->ca_baseaddr;
	ca->ca_reg[2] += ca->ca_baseaddr;

	if ((sc->sc_reg = mapiodev(ca->ca_reg[0], ca->ca_reg[1])) == NULL) {
		printf(": cannot map registers\n");
		return;
	}
	sc->sc_dmat = ca->ca_dmat;

	if ((sc->sc_dma = mapiodev(ca->ca_reg[2], ca->ca_reg[3])) == NULL) {
		printf(": cannot map DMA registers\n");
		goto nodma;
	}

	if ((sc->sc_dbdma = dbdma_alloc(sc->sc_dmat, BL_DBDMA_CMDS)) == NULL) {
		printf(": cannot alloc DMA descriptors\n");
		goto nodbdma;
	 }
	sc->sc_dmacmd = sc->sc_dbdma->d_addr;

	if ((error = bus_dmamem_alloc(sc->sc_dmat, BL_BUFSZ, 0, 0,
		sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT))) {
		printf(": cannot allocate DMA mem (%d)\n", error);
		goto nodmamem;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, sc->sc_bufseg, nseg,
	    BL_BUFSZ, (caddr_t *)&sc->sc_buf, BUS_DMA_NOWAIT))) {
		printf(": cannot map DMA mem (%d)\n", error);
		goto nodmamap;
	}
	sc->sc_bufpos = sc->sc_buf;

	if ((error = bus_dmamap_create(sc->sc_dmat, BL_BUFSZ, 1, BL_BUFSZ, 0,
	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap))) {
		printf(": cannot create DMA map (%d)\n", error);
		goto nodmacreate;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_bufmap, sc->sc_buf,
	    BL_BUFSZ, NULL, BUS_DMA_NOWAIT))) {
		printf(": cannot load DMA map (%d)\n", error);
		goto nodmaload;
	}
	/* XXX: Should probably extract this from the clock data
	 * property of the soundchip node */
	sc->sc_freq = 16384;

	OF_getprop(sc->sc_node, "interrupts", intr, sizeof(intr));
	/* output interrupt */
	sc->sc_intr = intr[2];
	type = intr[3] ? IST_LEVEL : IST_EDGE;

	printf(": irq %d\n", sc->sc_intr);

	macobio_enable(I2SClockOffset, I2S0EN);
	out32rb(sc->sc_reg + I2S_INT, I2S_INT_CLKSTOPPEND);
	macobio_disable(I2SClockOffset, I2S0CLKEN);
	for (error = 0; error < 1000; error++) {
		if (in32rb(sc->sc_reg + I2S_INT) & I2S_INT_CLKSTOPPEND) {
			error = 0;
			break;
		}
		delay(1);
	}
	if (error) {
		printf("%s: i2s timeout\n", sc->sc_dev.dv_xname);
		goto nodmaload;
	}

	mac_intr_establish(parent, sc->sc_intr, intr[3] ? IST_LEVEL :
	    type, IPL_AUDIO, xlights_intr, sc, sc->sc_dev.dv_xname);

	out32rb(sc->sc_reg + I2S_FORMAT, CLKSRC_VS);
	macobio_enable(I2SClockOffset, I2S0CLKEN);

	kthread_create_deferred(xlights_deferred, sc);
	timeout_set(&sc->sc_tmo, xlights_timeout, sc);
	return;
nodmaload:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap);
nodmacreate:
	bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_buf, BL_BUFSZ);
nodmamap:
	bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, nseg);
nodmamem:
	dbdma_free(sc->sc_dbdma);
nodbdma:
	unmapiodev((void *)sc->sc_dma, ca->ca_reg[3]);
nodma:
	unmapiodev(sc->sc_reg, ca->ca_reg[1]);
}