Пример #1
0
static void
uart_attach(device_t parent, device_t self, void *aux)
{
        struct obio_attach_args * const oba = aux;
        struct uart_softc * const sc = device_private(self);
	struct tty *tp;
	int maj, minor;

	sc->sc_dev = self;
        sc->sc_st = oba->oba_st;
        if (bus_space_map(oba->oba_st, oba->oba_addr, 256, 0, &sc->sc_ioh)) {
                aprint_error("unable to map device\n");
                return;
	}

	/* Establish the interrupt. */
	sc->sc_ih = adm5120_intr_establish(oba->oba_irq, INTR_FIQ, uart_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error("unable to establish interrupt\n");
		return;
	}
	REG_WRITE(UART_CR_REG,UART_CR_PORT_EN|UART_CR_RX_INT_EN|UART_CR_RX_TIMEOUT_INT_EN);

	maj = cdevsw_lookup_major(&uart_cdevsw);
	minor = device_unit(sc->sc_dev);

	tp = tty_alloc();
	tp->t_oproc = uart_start;
	tp->t_param = uart_param;
	sc->sc_tty = tp;
	tp->t_dev = makedev(maj, minor);
	tty_attach(tp);
	if (minor == 0 && uart_consattached) {
		/* attach as console*/
		cn_tab->cn_dev = tp->t_dev;
		aprint_normal(" console");
	}
        aprint_normal("\n");
}
Пример #2
0
static void
admsw_attach(device_t parent, device_t self, void *aux)
{
	uint8_t enaddr[ETHER_ADDR_LEN];
	struct admsw_softc *sc = device_private(self);
	struct obio_attach_args *aa = aux;
	struct ifnet *ifp;
	bus_dma_segment_t seg;
	int error, i, rseg;
	prop_data_t pd;

	printf(": ADM5120 Switch Engine, %d ports\n", SW_DEVS);

	sc->sc_dev = self;
	sc->sc_dmat = aa->oba_dt;
	sc->sc_st = aa->oba_st;

	pd = prop_dictionary_get(device_properties(self), "mac-address");

	if (pd == NULL) {
		enaddr[0] = 0x02;
		enaddr[1] = 0xaa;
		enaddr[2] = 0xbb;
		enaddr[3] = 0xcc;
		enaddr[4] = 0xdd;
		enaddr[5] = 0xee;
	} else
		memcpy(enaddr, prop_data_data_nocopy(pd), sizeof(enaddr));

	memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr));

	printf("%s: base Ethernet address %s\n", device_xname(sc->sc_dev),
	    ether_sprintf(enaddr));

	/* Map the device. */
	if (bus_space_map(sc->sc_st, aa->oba_addr, 512, 0, &sc->sc_ioh) != 0) {
		printf("%s: unable to map device\n", device_xname(sc->sc_dev));
		return;
	}

	/* Hook up the interrupt handler. */
	sc->sc_ih = adm5120_intr_establish(aa->oba_irq, INTR_IRQ, admsw_intr, sc);

	if (sc->sc_ih == NULL) {
		printf("%s: unable to register interrupt handler\n",
		    device_xname(sc->sc_dev));
		return;
	}

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmat,
	    sizeof(struct admsw_control_data), PAGE_SIZE, 0, &seg, 1, &rseg,
	    0)) != 0) {
		printf("%s: unable to allocate control data, error = %d\n",
		    device_xname(sc->sc_dev), error);
		return;
	}
	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
	    sizeof(struct admsw_control_data), (void *)&sc->sc_control_data,
	    0)) != 0) {
		printf("%s: unable to map control data, error = %d\n",
		    device_xname(sc->sc_dev), error);
		return;
	}
	if ((error = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct admsw_control_data), 1,
	    sizeof(struct admsw_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		printf("%s: unable to create control data DMA map, "
		    "error = %d\n", device_xname(sc->sc_dev), error);
		return;
	}
	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct admsw_control_data), NULL,
	    0)) != 0) {
		printf("%s: unable to load control data DMA map, error = %d\n",
		    device_xname(sc->sc_dev), error);
		return;
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < ADMSW_NTXHDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
		    2, MCLBYTES, 0, 0,
		    &sc->sc_txhsoft[i].ds_dmamap)) != 0) {
			printf("%s: unable to create txh DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			return;
		}
		sc->sc_txhsoft[i].ds_mbuf = NULL;
	}
	for (i = 0; i < ADMSW_NTXLDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
		    2, MCLBYTES, 0, 0,
		    &sc->sc_txlsoft[i].ds_dmamap)) != 0) {
			printf("%s: unable to create txl DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			return;
		}
		sc->sc_txlsoft[i].ds_mbuf = NULL;
	}

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < ADMSW_NRXHDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
		    MCLBYTES, 0, 0, &sc->sc_rxhsoft[i].ds_dmamap)) != 0) {
			printf("%s: unable to create rxh DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			return;
		}
		sc->sc_rxhsoft[i].ds_mbuf = NULL;
	}
	for (i = 0; i < ADMSW_NRXLDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
		    MCLBYTES, 0, 0, &sc->sc_rxlsoft[i].ds_dmamap)) != 0) {
			printf("%s: unable to create rxl DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			return;
		}
		sc->sc_rxlsoft[i].ds_mbuf = NULL;
	}

	admsw_init_bufs(sc);

	admsw_reset(sc);

	for (i = 0; i < SW_DEVS; i++) {
		ifmedia_init(&sc->sc_ifmedia[i], 0, admsw_mediachange, admsw_mediastatus);
		ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_10_T, 0, NULL);
		ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
		ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_100_TX, 0, NULL);
		ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
		ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_AUTO, 0, NULL);
		ifmedia_set(&sc->sc_ifmedia[i], IFM_ETHER|IFM_AUTO);

		ifp = &sc->sc_ethercom[i].ec_if;
		strcpy(ifp->if_xname, device_xname(sc->sc_dev));
		ifp->if_xname[5] += i;
		ifp->if_softc = sc;
		ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
		ifp->if_ioctl = admsw_ioctl;
		ifp->if_start = admsw_start;
		ifp->if_watchdog = admsw_watchdog;
		ifp->if_init = admsw_init;
		ifp->if_stop = admsw_stop;
		ifp->if_capabilities |= IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx;
		IFQ_SET_MAXLEN(&ifp->if_snd, max(ADMSW_NTXLDESC, IFQ_MAXLEN));
		IFQ_SET_READY(&ifp->if_snd);

		/* Attach the interface. */
		if_attach(ifp);
		ether_ifattach(ifp, enaddr);
		enaddr[5]++;
	}

#ifdef ADMSW_EVENT_COUNTERS
	evcnt_attach_dynamic(&sc->sc_ev_txstall, EVCNT_TYPE_MISC,
	    NULL, device_xname(sc->sc_dev), "txstall");
	evcnt_attach_dynamic(&sc->sc_ev_rxstall, EVCNT_TYPE_MISC,
	    NULL, device_xname(sc->sc_dev), "rxstall");
	evcnt_attach_dynamic(&sc->sc_ev_txintr, EVCNT_TYPE_MISC,
	    NULL, device_xname(sc->sc_dev), "txintr");
	evcnt_attach_dynamic(&sc->sc_ev_rxintr, EVCNT_TYPE_MISC,
	    NULL, device_xname(sc->sc_dev), "rxintr");
#if 1
	evcnt_attach_dynamic(&sc->sc_ev_rxsync, EVCNT_TYPE_MISC,
	    NULL, device_xname(sc->sc_dev), "rxsync");
#endif
#endif

	admwdog_attach(sc);

	/* Make sure the interface is shutdown during reboot. */
	sc->sc_sdhook = shutdownhook_establish(admsw_shutdown, sc);
	if (sc->sc_sdhook == NULL)
		printf("%s: WARNING: unable to establish shutdown hook\n",
		    device_xname(sc->sc_dev));

	/* leave interrupts and cpu port disabled */
	return;
}