Пример #1
0
int
wdc_obio_detach(struct device *self, int flags)
{
	struct wdc_obio_softc *sc = (struct wdc_obio_softc *)self;
	struct channel_softc *chp = &sc->wdc_channel;
	int error;

	if ((error = wdcdetach(chp, flags)) != 0)
		return (error);

	free(chp->ch_queue, M_DEVBUF);

	if (sc->sc_use_dma) {
		unmapiodev((void *)sc->sc_dmareg, sc->sc_dmasize);
		dbdma_free(sc->sc_dbdma);
	}
	mac_intr_disestablish(NULL, sc->sc_ih);

	bus_space_unmap(chp->cmd_iot, chp->cmd_ioh, sc->sc_cmdsize);
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap);

	return (0);
}
Пример #2
0
void
mc_attach(struct device *parent, struct device *self, void *aux)
{
	struct confargs *ca = aux;
	struct mc_softc *sc = (struct mc_softc *)self;
	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
	u_int8_t lladdr[ETHER_ADDR_LEN];
	int nseg, error;

	if (OF_getprop(ca->ca_node, "local-mac-address", lladdr,
	    ETHER_ADDR_LEN) != ETHER_ADDR_LEN) {
		printf(": failed to get MAC address.\n");
		return;
	}

	ca->ca_reg[0] += ca->ca_baseaddr;
	ca->ca_reg[2] += ca->ca_baseaddr;
	ca->ca_reg[4] += 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;
	sc->sc_tail = 0;

	if ((sc->sc_txdma = mapiodev(ca->ca_reg[2], ca->ca_reg[3])) == NULL) {
		printf(": cannot map TX DMA registers\n");
		goto notxdma;
	}
	if ((sc->sc_rxdma = mapiodev(ca->ca_reg[4], ca->ca_reg[5])) == NULL) {
		printf(": cannot map RX DMA registers\n");
		goto norxdma;
	}
	if ((sc->sc_txdbdma = dbdma_alloc(sc->sc_dmat, 2)) == NULL) {
		printf(": cannot alloc TX DMA descriptors\n");
		goto notxdbdma;
	}
	sc->sc_txdmacmd = sc->sc_txdbdma->d_addr;

	if ((sc->sc_rxdbdma = dbdma_alloc(sc->sc_dmat, 8 + 1)) == NULL) {
		printf(": cannot alloc RX DMA descriptors\n");
		goto norxdbdma;
	}
	sc->sc_rxdmacmd = sc->sc_rxdbdma->d_addr;

	if ((error = bus_dmamem_alloc(sc->sc_dmat, MACE_BUFSZ, PAGE_SIZE, 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,
	    MACE_BUFSZ, &sc->sc_txbuf, BUS_DMA_NOWAIT))) {
		printf(": cannot map DMA mem (%d)\n", error);
		goto nodmamap;
	}

	if ((error = bus_dmamap_create(sc->sc_dmat, MACE_BUFSZ, 1, MACE_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_txbuf,
	    MACE_BUFSZ, NULL, BUS_DMA_NOWAIT))) {
		printf(": cannot load DMA map (%d)\n", error);
		goto nodmaload;
	}

	sc->sc_txbuf_pa = sc->sc_bufmap->dm_segs->ds_addr;
	sc->sc_rxbuf = sc->sc_txbuf + MACE_BUFLEN * MACE_TXBUFS;
	sc->sc_rxbuf_pa = sc->sc_txbuf_pa + MACE_BUFLEN * MACE_TXBUFS;

	printf(": irq %d,%d,%d", ca->ca_intr[0], ca->ca_intr[1],
	    ca->ca_intr[2]);

	/* disable receive DMA */
	dbdma_reset(sc->sc_rxdma);

	/* disable transmit DMA */
	dbdma_reset(sc->sc_txdma);

	/* install interrupt handlers */
	mac_intr_establish(parent, ca->ca_intr[2], IST_LEVEL, IPL_NET,
	    mc_dmaintr, sc, sc->sc_dev.dv_xname);
	mac_intr_establish(parent, ca->ca_intr[0],  IST_LEVEL, IPL_NET,
	    mc_intr, sc, sc->sc_dev.dv_xname);

	sc->sc_biucc = XMTSP_64;
	sc->sc_fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU |
	    XMTBRST | RCVBRST;
	sc->sc_plscc = PORTSEL_GPSI | ENPLSIO;

	/* reset the chip and disable all interrupts */
	NIC_PUT(sc, MACE_BIUCC, SWRST);
	DELAY(100);

	NIC_PUT(sc, MACE_IMR, ~0);

	bcopy(lladdr, sc->sc_enaddr, ETHER_ADDR_LEN);
	bcopy(sc->sc_enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
	printf(": address %s\n", ether_sprintf(lladdr));

	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_ioctl = mc_ioctl;
	ifp->if_start = mc_start;
	ifp->if_flags =
		IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
	ifp->if_watchdog = mc_watchdog;
	ifp->if_timer = 0;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	ether_ifattach(ifp);

	return;
nodmaload:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap);
nodmacreate:
	bus_dmamem_unmap(sc->sc_dmat, sc->sc_txbuf, MACE_BUFSZ);
nodmamap:
	bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, 1);
nodmamem:
	dbdma_free(sc->sc_rxdbdma);
norxdbdma:
	dbdma_free(sc->sc_txdbdma);
notxdbdma:
	unmapiodev((void *)sc->sc_rxdma, ca->ca_reg[5]);
norxdma:
	unmapiodev((void *)sc->sc_txdma, ca->ca_reg[3]);
notxdma:
	unmapiodev(sc->sc_reg, ca->ca_reg[1]);
}
Пример #3
0
static void
mbattach(struct device *parent, struct device *self, void *aux)
{
	struct mainbus_softc *sc = (struct mainbus_softc *)self;
	struct confargs nca;
	char name[64], *t = NULL;
	int reg[4], cpucnt;
	int node, len, slen;

	node = OF_peer(0);
	len = OF_getprop(node, "model", name, sizeof(name));
	if (len > 1) {
		name[len] = '\0';
		slen = strlen(name)+1;
		if ((t = malloc(slen, M_DEVBUF, M_NOWAIT)) != NULL)
			strlcpy(t, name, slen);

	}

	len = OF_getprop(node, "compatible", name, sizeof(name));
	if (len > 1) {
		name[len] = '\0';
		/* Old World Macintosh */
		if ((strncmp(name, "AAPL", 4)) == 0) {
			hw_vendor = "Apple Computer, Inc.";
			slen = strlen(t) + strlen(name) - 3;
			if ((hw_prod = malloc(slen, M_DEVBUF, M_NOWAIT)) != NULL) {
				snprintf(hw_prod, slen, "%s %s", t, name + 5);
				free(t, M_DEVBUF);
			}
		} else {
			/* New World Macintosh or Unknown */
			hw_vendor = "Apple Computer, Inc.";
			hw_prod = t;
		}
	}
	printf(": model %s\n", hw_prod);

	sc->sc_bus.bh_dv = (struct device *)sc;
	sc->sc_bus.bh_type = BUS_MAIN;
	sc->sc_bus.bh_intr_establish = mb_intr_establish;
	sc->sc_bus.bh_intr_disestablish = mb_intr_disestablish;
	sc->sc_bus.bh_matchname = mb_matchname;

	/*
	 * Try to find and attach all of the CPUs in the machine.
	 */

	cpucnt = 0;
	node = OF_finddevice("/cpus");
	if (node != -1) {
		for (node = OF_child(node); node != 0; node = OF_peer(node)) {
			u_int32_t cpunum;
			int len;
			len = OF_getprop(node, "reg", &cpunum, sizeof cpunum);
			if (len == 4 && cpucnt == cpunum) {
				nca.ca_name = "cpu";
				nca.ca_bus = &sc->sc_bus;
				nca.ca_reg = reg;
				reg[0] = cpucnt;
				config_found(self, &nca, mbprint);
				cpucnt++;
			}
		}
	}
	if (cpucnt == 0) {
		nca.ca_name = "cpu";
		nca.ca_bus = &sc->sc_bus;
		nca.ca_reg = reg;
		reg[0] = 0;
		config_found(self, &nca, mbprint);
	}

	/*
	 * Special hack for SMP old world macs which lack /cpus and only have
	 * one cpu node.
	 */
	node = OF_finddevice("/hammerhead");
	if (node != -1) {
		len = OF_getprop(node, "reg", reg, sizeof(reg));
		if (len >= 2) {
			u_char *hh_base;
			int twoway = 0;

			if ((hh_base = mapiodev(reg[0], reg[1])) != NULL) {
				twoway = in32rb(hh_base + HH_REG_CONF) & 0x02;
				unmapiodev(hh_base, reg[1]);
			}
			if (twoway) {
				nca.ca_name = "cpu";
				nca.ca_bus = &sc->sc_bus;
				nca.ca_reg = reg;
				reg[0] = 1;
				config_found(self, &nca, mbprint);
			}
		}
	}

	for (node = OF_child(OF_peer(0)); node; node=OF_peer(node)) {
		bzero (name, sizeof(name));
		if (OF_getprop(node, "device_type", name,
		    sizeof(name)) <= 0) {
			if (OF_getprop(node, "name", name,
			    sizeof(name)) <= 0)
				printf ("name not found on node %x\n",
				    node);
				continue;
		}
		if (strcmp(name, "memory") == 0) {
			nca.ca_name = "mem";
			nca.ca_node = node;
			nca.ca_bus = &sc->sc_bus;
			config_found(self, &nca, mbprint);
		}
		if (strcmp(name, "memory-controller") == 0) {
			nca.ca_name = "memc";
			nca.ca_node = node;
			nca.ca_bus = &sc->sc_bus;
			config_found(self, &nca, mbprint);
		}
		if (strcmp(name, "pci") == 0) {
			nca.ca_name = "mpcpcibr";
			nca.ca_node = node;
			nca.ca_bus = &sc->sc_bus;
			config_found(self, &nca, mbprint);
		}
		if (strcmp(name, "ht") == 0) {
			nca.ca_name = "ht";
			nca.ca_node = node;
			nca.ca_bus = &sc->sc_bus;
			config_found(self, &nca, mbprint);
		}
		if (strcmp(name, "smu") == 0) {
			nca.ca_name = "smu";
			nca.ca_node = node;
			nca.ca_bus = &sc->sc_bus;
			config_found(self, &nca, mbprint);
		}
	}
}
Пример #4
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]);
}