Ejemplo n.º 1
0
void
rump_hyperentropy_init(void)
{

	if (rump_threads) {
		rndsource_setcb(&rndsrc, feedrandom, &rndsrc);
		rnd_attach_source(&rndsrc, "rump_hyperent", RND_TYPE_VM,
		    RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);
	} else {
		/* without threads, just fill the pool */
		rnd_attach_source(&rndsrc, "rump_hyperent", RND_TYPE_VM,
		    RND_FLAG_NO_ESTIMATE);
		feedrandom(RND_POOLBITS/NBBY, NULL);
	}
}
Ejemplo n.º 2
0
static int
pckbc_attach_slot(struct pckbc_softc *sc, pckbc_slot_t slot)
{
	struct pckbc_internal *t = sc->id;
	void *sdata;
	device_t child;
	int alloced = 0;

	if (t->t_slotdata[slot] == NULL) {
		sdata = malloc(sizeof(struct pckbc_slotdata),
		    M_DEVBUF, M_NOWAIT);
		if (sdata == NULL) {
			aprint_error_dev(sc->sc_dv, "no memory\n");
			return (0);
		}
		t->t_slotdata[slot] = sdata;
		pckbc_init_slotdata(t->t_slotdata[slot]);
		alloced++;
	}

	child = pckbport_attach_slot(sc->sc_dv, t->t_pt, slot);

	if (child == NULL && alloced) {
		free(t->t_slotdata[slot], M_DEVBUF);
		t->t_slotdata[slot] = NULL;
	}

	if (child != NULL && t->t_slotdata[slot] != NULL)
		rnd_attach_source(&t->t_slotdata[slot]->rnd_source,
		    device_xname(child), RND_TYPE_TTY, 0);

	return child != NULL;
}
Ejemplo n.º 3
0
static void
ingenic_rng_attach(device_t parent, device_t self, void *aux)
{
	struct ingenic_rng_softc * const sc = device_private(self);
	const struct apbus_attach_args * const aa = aux;
	bus_addr_t addr = aa->aa_addr;
	int error;

	sc->sc_dev = self;
	sc->sc_bst = aa->aa_bst;
	if (addr == 0)
		addr = JZ_RNG;

	error = bus_space_map(aa->aa_bst, addr, 4, 0, &sc->sc_bsh);
	if (error) {
		aprint_error_dev(self,
		    "can't map registers for %s: %d\n", aa->aa_name, error);
		return;
	}

	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);

	aprint_naive(": Ingenic random number generator\n");
	aprint_normal(": Ingenic random number generator\n");

	rndsource_setcb(&sc->sc_rndsource, ingenic_rng_get, sc);
	rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG,
	    RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB);

	ingenic_rng_get(RND_POOLBITS / NBBY, sc);
}
Ejemplo n.º 4
0
static void
bcmrng_attach(device_t parent, device_t self, void *aux)
{
    struct bcm2835rng_softc *sc = device_private(self);
    struct amba_attach_args *aaa = aux;
    uint32_t ctrl;

    aprint_naive("\n");
    aprint_normal(": RNG\n");

    sc->sc_dev = self;
    sc->sc_iot = aaa->aaa_iot;

    if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_RNG_SIZE, 0,
                      &sc->sc_ioh)) {
        aprint_error_dev(sc->sc_dev, "unable to map device\n");
        goto fail0;
    }

    /* discard initial numbers, broadcom says they are "less random" */
    bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS, 0x40000);

    /* enable rng */
    ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL);
    ctrl |= RNG_CTRL_EN;
    bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL, ctrl);

    /* set up a softint for adding data */
    mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL);
    sc->sc_bytes_wanted = 0;
    sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
                                   &bcmrng_get_intr, sc);
    if (sc->sc_sih == NULL) {
        aprint_error_dev(sc->sc_dev, "unable to establish softint");
        goto fail1;
    }

    /* set up an rndsource */
    mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL);
    rndsource_setcb(&sc->sc_rndsource, &bcmrng_get_cb, sc);
    rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG,
                      RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);

    /* get some initial entropy ASAP */
    bcmrng_get_cb(RND_POOLBITS / NBBY, sc);

    /* Success!  */
    return;

fail1:
    mutex_destroy(&sc->sc_intr_lock);
    bus_space_unmap(aaa->aaa_iot, sc->sc_ioh, BCM2835_RNG_SIZE);
fail0:
    return;
}
Ejemplo n.º 5
0
static void
ed_mca_attach(device_t parent, device_t self, void *aux)
{
    struct ed_softc *ed = device_private(self);
    struct edc_mca_softc *sc = device_private(parent);
    struct ed_attach_args *eda = aux;
    char pbuf[8];
    int drv_flags;

    ed->sc_dev = self;
    ed->edc_softc = sc;
    ed->sc_devno  = eda->edc_drive;
    edc_add_disk(sc, ed);

    bufq_alloc(&ed->sc_q, "disksort", BUFQ_SORT_RAWBLOCK);
    mutex_init(&ed->sc_q_lock, MUTEX_DEFAULT, IPL_VM);

    if (ed_get_params(ed, &drv_flags)) {
        printf(": IDENTIFY failed, no disk found\n");
        return;
    }

    format_bytes(pbuf, sizeof(pbuf),
                 (u_int64_t) ed->sc_capacity * DEV_BSIZE);
    printf(": %s, %u cyl, %u head, %u sec, 512 bytes/sect x %u sectors\n",
           pbuf,
           ed->cyl, ed->heads, ed->sectors,
           ed->sc_capacity);

    printf("%s: %u spares/cyl, %s, %s, %s, %s, %s\n",
           device_xname(ed->sc_dev), ed->spares,
           (drv_flags & (1 << 0)) ? "NoRetries" : "Retries",
           (drv_flags & (1 << 1)) ? "Removable" : "Fixed",
           (drv_flags & (1 << 2)) ? "SkewedFormat" : "NoSkew",
           (drv_flags & (1 << 3)) ? "ZeroDefect" : "Defects",
           (drv_flags & (1 << 4)) ? "InvalidSecondary" : "SecondaryOK"
          );

    /*
     * Initialize and attach the disk structure.
     */
    disk_init(&ed->sc_dk, device_xname(ed->sc_dev), &eddkdriver);
    disk_attach(&ed->sc_dk);
    rnd_attach_source(&ed->rnd_source, device_xname(ed->sc_dev),
                      RND_TYPE_DISK, RND_FLAG_DEFAULT);

    ed->sc_flags |= EDF_INIT;

    /*
     * XXX We should try to discovery wedges here, but
     * XXX that would mean being able to do I/O.  Should
     * XXX use config_defer() here.
     */
}
Ejemplo n.º 6
0
Archivo: ld.c Proyecto: MarginC/kame
void
ldattach(struct ld_softc *sc)
{
	char buf[9];

	if ((sc->sc_flags & LDF_ENABLED) == 0) {
		printf("%s: disabled\n", sc->sc_dv.dv_xname);
		return;
	}

	/* Initialise and attach the disk structure. */
	sc->sc_dk.dk_driver = &lddkdriver;
	sc->sc_dk.dk_name = sc->sc_dv.dv_xname;
	disk_attach(&sc->sc_dk);

	if (sc->sc_maxxfer > MAXPHYS)
		sc->sc_maxxfer = MAXPHYS;

	/* Build synthetic geometry. */
	if (sc->sc_secperunit <= 528 * 2048)		/* 528MB */
		sc->sc_nheads = 16;
	else if (sc->sc_secperunit <= 1024 * 2048)	/* 1GB */
		sc->sc_nheads = 32;
	else if (sc->sc_secperunit <= 21504 * 2048)	/* 21GB */
		sc->sc_nheads = 64;
	else if (sc->sc_secperunit <= 43008 * 2048)	/* 42GB */
		sc->sc_nheads = 128;
	else
		sc->sc_nheads = 255;

	sc->sc_nsectors = 63;
	sc->sc_ncylinders = sc->sc_secperunit / 
	    (sc->sc_nheads * sc->sc_nsectors);

	format_bytes(buf, sizeof(buf), (u_int64_t)sc->sc_secperunit *
	    sc->sc_secsize);
	printf("%s: %s, %d cyl, %d head, %d sec, %d bytes/sect x %d sectors\n",
	    sc->sc_dv.dv_xname, buf, sc->sc_ncylinders, sc->sc_nheads,
	    sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit);

#if NRND > 0
	/* Attach the device into the rnd source list. */
	rnd_attach_source(&sc->sc_rnd_source, sc->sc_dv.dv_xname,
	    RND_TYPE_DISK, 0);
#endif

	/* Set the `shutdownhook'. */
	if (ld_sdh == NULL)
		ld_sdh = shutdownhook_establish(ldshutdown, NULL);
	BUFQ_INIT(&sc->sc_bufq);
}
Ejemplo n.º 7
0
void
ucom_attach(device_t parent, device_t self, void *aux)
{
	struct ucom_softc *sc = device_private(self);
	struct ucom_attach_args *uca = aux;
	struct tty *tp;

	if (uca->info != NULL)
		aprint_normal(": %s", uca->info);
	aprint_normal("\n");

	sc->sc_dev = self;
	sc->sc_udev = uca->device;
	sc->sc_iface = uca->iface;
	sc->sc_bulkout_no = uca->bulkout;
	sc->sc_bulkin_no = uca->bulkin;
	sc->sc_ibufsize = uca->ibufsize;
	sc->sc_ibufsizepad = uca->ibufsizepad;
	sc->sc_obufsize = uca->obufsize;
	sc->sc_opkthdrlen = uca->opkthdrlen;
	sc->sc_methods = uca->methods;
	sc->sc_parent = uca->arg;
	sc->sc_portno = uca->portno;

	sc->sc_lsr = 0;
	sc->sc_msr = 0;
	sc->sc_mcr = 0;
	sc->sc_tx_stopped = 0;
	sc->sc_swflags = 0;
	sc->sc_opening = 0;
	sc->sc_refcnt = 0;
	sc->sc_dying = 0;

	sc->sc_si = softint_establish(SOFTINT_NET, ucom_softintr, sc);

	tp = tty_alloc();
	tp->t_oproc = ucomstart;
	tp->t_param = ucomparam;
	tp->t_hwiflow = ucomhwiflow;
	sc->sc_tty = tp;

	DPRINTF(("ucom_attach: tty_attach %p\n", tp));
	tty_attach(tp);

	rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, RND_FLAG_DEFAULT);

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
	return;
}
Ejemplo n.º 8
0
/*
 * Controller is working, and drive responded.  Attach it.
 */
void
fdattach(device_t parent, device_t self, void *aux)
{
	struct fdc_softc *fdc = device_private(parent);
	struct fd_softc *fd = device_private(self);
	struct fdc_attach_args *fa = aux;
	const struct fd_type *type = fa->fa_deftype;
	int drive = fa->fa_drive;

	fd->sc_dev = self;

	callout_init(&fd->sc_motoron_ch, 0);
	callout_init(&fd->sc_motoroff_ch, 0);

	/* XXX Allow `flags' to override device type? */

	if (type)
		aprint_normal(": %s, %d cyl, %d head, %d sec\n", type->name,
		    type->cyls, type->heads, type->sectrac);
	else
		aprint_normal(": density unknown\n");

	bufq_alloc(&fd->sc_q, "disksort", BUFQ_SORT_CYLINDER);
	fd->sc_cylin = -1;
	fd->sc_drive = drive;
	fd->sc_deftype = type;
	fdc->sc_fd[drive] = fd;

	/*
	 * Initialize and attach the disk structure.
	 */
	disk_init(&fd->sc_dk, device_xname(fd->sc_dev), &fddkdriver);
	disk_attach(&fd->sc_dk);

	/*
	 * Establish a mountroot hook.
	 */
	fd->sc_roothook =
	    mountroothook_establish(fd_mountroot_hook, fd->sc_dev);

#if NRND > 0
	rnd_attach_source(&fd->rnd_source, device_xname(fd->sc_dev),
			  RND_TYPE_DISK, 0);
#endif

	fd_set_properties(fd);

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "cannot set power mgmt handler\n");
}
Ejemplo n.º 9
0
void
dk_attach(struct dk_softc *dksc)
{
	KASSERT(dksc->sc_dev != NULL);

	mutex_init(&dksc->sc_iolock, MUTEX_DEFAULT, IPL_VM);
	dksc->sc_flags |= DKF_READYFORDUMP;
#ifdef DIAGNOSTIC
	dksc->sc_flags |= DKF_WARNLABEL | DKF_LABELSANITY;
#endif

	/* Attach the device into the rnd source list. */
	rnd_attach_source(&dksc->sc_rnd_source, dksc->sc_xname,
	    RND_TYPE_DISK, RND_FLAG_DEFAULT);
}
Ejemplo n.º 10
0
static void
rdattach(device_t parent, device_t self, void *aux)
{
	struct rd_softc *sc = device_private(self);
	struct hpibbus_attach_args *ha = aux;

	sc->sc_dev = self;
	bufq_alloc(&sc->sc_tab, "disksort", BUFQ_SORT_RAWBLOCK);

	if (rdident(parent, sc, ha) == 0) {
		aprint_error(": didn't respond to describe command!\n");
		return;
	}

	/*
	 * Initialize and attach the disk structure.
	 */
	memset(&sc->sc_dkdev, 0, sizeof(sc->sc_dkdev));
	disk_init(&sc->sc_dkdev, device_xname(sc->sc_dev), NULL);
	disk_attach(&sc->sc_dkdev);

	sc->sc_slave = ha->ha_slave;
	sc->sc_punit = ha->ha_punit;

	callout_init(&sc->sc_restart_ch, 0);

	/* Initialize the hpib job queue entry */
	sc->sc_hq.hq_softc = sc;
	sc->sc_hq.hq_slave = sc->sc_slave;
	sc->sc_hq.hq_start = rdstart;
	sc->sc_hq.hq_go = rdgo;
	sc->sc_hq.hq_intr = rdintr;

	sc->sc_flags = RDF_ALIVE;
#ifdef DEBUG
	/* always report errors */
	if (rddebug & RDB_ERROR)
		rderrthresh = 0;
#endif
	/*
	 * attach the device into the random source list
	 */
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
	    RND_TYPE_DISK, RND_FLAG_DEFAULT);
}
Ejemplo n.º 11
0
void
mb8795_config(struct mb8795_softc *sc, int *media, int nmedia, int defmedia)
{
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;

	DPRINTF(("%s: mb8795_config()\n",device_xname(sc->sc_dev)));

	/* Initialize ifnet structure. */
	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_start = mb8795_start;
	ifp->if_ioctl = mb8795_ioctl;
	ifp->if_watchdog = mb8795_watchdog;
	ifp->if_flags =
		IFF_BROADCAST | IFF_NOTRAILERS;

	/* Initialize media goo. */
	ifmedia_init(&sc->sc_media, 0, mb8795_mediachange,
		     mb8795_mediastatus);
	if (media != NULL) {
		int i;
		for (i = 0; i < nmedia; i++)
			ifmedia_add(&sc->sc_media, media[i], 0, NULL);
		ifmedia_set(&sc->sc_media, defmedia);
	} else {
		ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
	}

  /* Attach the interface. */
  if_attach(ifp);
  ether_ifattach(ifp, sc->sc_enaddr);

  sc->sc_sh = shutdownhook_establish(mb8795_shutdown, sc);
  if (sc->sc_sh == NULL)
    panic("mb8795_config: can't establish shutdownhook");

  rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
                    RND_TYPE_NET, RND_FLAG_DEFAULT);

	DPRINTF(("%s: leaving mb8795_config()\n",device_xname(sc->sc_dev)));
}
Ejemplo n.º 12
0
static void
ingenic_rng_attach(device_t parent, device_t self, void *aux)
{
	struct ingenic_rng_softc * const sc = device_private(self);
	struct apbus_attach_args * const aa = aux;
	int error;

	sc->sc_dev = self;
	sc->sc_bst = aa->aa_bst;
	if (aa->aa_addr == 0) {
		aa->aa_addr = JZ_RNG;
	}

	error = bus_space_map(aa->aa_bst, aa->aa_addr, 4, 0, &sc->sc_bsh);
	if (error) {
		aprint_error_dev(self,
			"can't map registers for %s: %d\n", aa->aa_name, error);
		return;
	}

	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL);
	mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL);
	
	aprint_naive(": Ingenic random number generator\n");
	aprint_normal(": Ingenic random number generator\n");

	sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
	    ingenic_rng_get_intr, sc);
	if (sc->sc_sih == NULL) {
		aprint_error_dev(self, "couldn't establish softint\n");
		return;
	}

	rndsource_setcb(&sc->sc_rndsource, ingenic_rng_get_cb, sc);
	rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG,
	    RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB);

	ingenic_rng_get_cb(RND_POOLBITS / NBBY, sc);
}
Ejemplo n.º 13
0
Archivo: xbd.c Proyecto: MarginC/kame
static void
xbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct xbd_attach_args *xbda = (struct xbd_attach_args *)aux;
	struct xbd_softc *xs = (struct xbd_softc *)self;

	aprint_normal(": Xen Virtual Block Device");

	simple_lock_init(&xs->sc_slock);
	dk_sc_init(&xs->sc_dksc, xs, xs->sc_dev.dv_xname);
	xbdinit(xs, xbda->xa_xd, xbda->xa_dkintf);
	if (diskcookies) {
		/* XXX beware that xs->sc_xd_device is a long */
		sysctl_createv(NULL, 0, &diskcookies, NULL,
		    0,
		    CTLTYPE_INT, xs->sc_dev.dv_xname, NULL,
		    NULL, 0, &xs->sc_xd_device, 0,
		    CTL_CREATE, CTL_EOL);
	}
#if NRND > 0
	rnd_attach_source(&xs->rnd_source, xs->sc_dev.dv_xname,
	    RND_TYPE_DISK, 0);
#endif
}
Ejemplo n.º 14
0
/*
 * ae_attach:
 *
 *	Attach an ae interface to the system.
 */
void
ae_attach(device_t parent, device_t self, void *aux)
{
	const uint8_t *enaddr;
	prop_data_t ea;
	struct ae_softc *sc = device_private(self);
	struct arbus_attach_args *aa = aux;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	int i, error;

	sc->sc_dev = self;

	callout_init(&sc->sc_tick_callout, 0);

	printf(": Atheros AR531X 10/100 Ethernet\n");

	/*
	 * Try to get MAC address.
	 */
	ea = prop_dictionary_get(device_properties(sc->sc_dev), "mac-address");
	if (ea == NULL) {
		printf("%s: unable to get mac-addr property\n",
		    device_xname(sc->sc_dev));
		return;
	}
	KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
	KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
	enaddr = prop_data_data_nocopy(ea);

	/* Announce ourselves. */
	printf("%s: Ethernet address %s\n", device_xname(sc->sc_dev),
	    ether_sprintf(enaddr));

	sc->sc_cirq = aa->aa_cirq;
	sc->sc_mirq = aa->aa_mirq;
	sc->sc_st = aa->aa_bst;
	sc->sc_dmat = aa->aa_dmat;

	SIMPLEQ_INIT(&sc->sc_txfreeq);
	SIMPLEQ_INIT(&sc->sc_txdirtyq);

	/*
	 * Map registers.
	 */
	sc->sc_size = aa->aa_size;
	if ((error = bus_space_map(sc->sc_st, aa->aa_addr, sc->sc_size, 0,
	    &sc->sc_sh)) != 0) {
		printf("%s: unable to map registers, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_0;
	}

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmat,
	    sizeof(struct ae_control_data), PAGE_SIZE, 0, &sc->sc_cdseg,
	    1, &sc->sc_cdnseg, 0)) != 0) {
		printf("%s: unable to allocate control data, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_1;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg,
	    sizeof(struct ae_control_data), (void **)&sc->sc_control_data,
	    BUS_DMA_COHERENT)) != 0) {
		printf("%s: unable to map control data, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_2;
	}

	if ((error = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct ae_control_data), 1,
	    sizeof(struct ae_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);
		goto fail_3;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct ae_control_data), NULL,
	    0)) != 0) {
		printf("%s: unable to load control data DMA map, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_4;
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < AE_TXQUEUELEN; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
		    AE_NTXSEGS, MCLBYTES, 0, 0,
		    &sc->sc_txsoft[i].txs_dmamap)) != 0) {
			printf("%s: unable to create tx DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			goto fail_5;
		}
	}

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < AE_NRXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
		    MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
			printf("%s: unable to create rx DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			goto fail_6;
		}
		sc->sc_rxsoft[i].rxs_mbuf = NULL;
	}

	/*
	 * Reset the chip to a known state.
	 */
	ae_reset(sc);

	/*
	 * From this point forward, the attachment cannot fail.  A failure
	 * before this point releases all resources that may have been
	 * allocated.
	 */
	sc->sc_flags |= AE_ATTACHED;

	/*
	 * Initialize our media structures.  This may probe the MII, if
	 * present.
	 */
	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = ae_mii_readreg;
	sc->sc_mii.mii_writereg = ae_mii_writereg;
	sc->sc_mii.mii_statchg = ae_mii_statchg;
	sc->sc_ethercom.ec_mii = &sc->sc_mii;
	ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
	    ether_mediastatus);
	mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);

	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);

	sc->sc_tick = ae_mii_tick;

	strcpy(ifp->if_xname, device_xname(sc->sc_dev));
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	sc->sc_if_flags = ifp->if_flags;
	ifp->if_ioctl = ae_ioctl;
	ifp->if_start = ae_start;
	ifp->if_watchdog = ae_watchdog;
	ifp->if_init = ae_init;
	ifp->if_stop = ae_stop;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * We can support 802.1Q VLAN-sized frames.
	 */
	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;

	/*
	 * Attach the interface.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, enaddr);
	ether_set_ifflags_cb(&sc->sc_ethercom, ae_ifflags_cb);

	rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
	    RND_TYPE_NET, RND_FLAG_DEFAULT);

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

	/*
	 * Add a suspend hook to make sure we come back up after a
	 * resume.
	 */
	sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev),
	    ae_power, sc);
	if (sc->sc_powerhook == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
		    device_xname(sc->sc_dev));
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_6:
	for (i = 0; i < AE_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_rxsoft[i].rxs_dmamap);
	}
 fail_5:
	for (i = 0; i < AE_TXQUEUELEN; i++) {
		if (sc->sc_txsoft[i].txs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_txsoft[i].txs_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
 fail_4:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
 fail_3:
	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
	    sizeof(struct ae_control_data));
 fail_2:
	bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
 fail_1:
	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size);
 fail_0:
	return;
}
Ejemplo n.º 15
0
void
viornd_attach( device_t parent, device_t self, void *aux)
{
	struct viornd_softc *sc = device_private(self);
	struct virtio_softc *vsc = device_private(parent);
	bus_dma_segment_t segs[1];
	int nsegs;
	int error;
	uint32_t features;
	char buf[256];

	vsc->sc_vqs = &sc->sc_vq;
	vsc->sc_nvqs = 1;
	vsc->sc_config_change = NULL;
	if (vsc->sc_child != NULL)
		panic("already attached to something else");
	vsc->sc_child = self;
	vsc->sc_ipl = IPL_NET;
	vsc->sc_intrhand = virtio_vq_intr;
	sc->sc_virtio = vsc;
	sc->sc_dev = self;

	features = virtio_negotiate_features(vsc, 0);
	snprintb(buf, sizeof(buf), VIRTIO_COMMON_FLAG_BITS, features);
	aprint_normal(": Features: %s\n", buf);
	aprint_naive("\n");


	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM);

	error = bus_dmamem_alloc(vsc->sc_dmat, 
				 VIRTIO_PAGE_SIZE, 0, 0, segs, 1, &nsegs,
				 BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW);
	if (error) {
		aprint_error_dev(sc->sc_dev, "can't alloc dmamem: %d\n",
				 error);
		goto alloc_failed;
	}

	error = bus_dmamem_map(vsc->sc_dmat, segs, nsegs, VIORND_BUFSIZE,
			       &sc->sc_buf, BUS_DMA_NOWAIT);
	if (error) {
		aprint_error_dev(sc->sc_dev, "can't map dmamem: %d\n", error);
		goto map_failed;
	}

	error = bus_dmamap_create(vsc->sc_dmat, VIORND_BUFSIZE, 1,
				  VIORND_BUFSIZE, 0,
				  BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
				  &sc->sc_dmamap);
	if (error) {
		aprint_error_dev(sc->sc_dev, "can't alloc dmamap: %d\n",
				 error);
		goto create_failed;
	}

	error = bus_dmamap_load(vsc->sc_dmat, sc->sc_dmamap,
	    			sc->sc_buf, VIORND_BUFSIZE, NULL,
				BUS_DMA_NOWAIT|BUS_DMA_READ);
	if (error) {
		aprint_error_dev(sc->sc_dev, "can't load dmamap: %d\n",
				 error);
		goto load_failed;
	}

	error = virtio_alloc_vq(vsc, &sc->sc_vq, 0, VIORND_BUFSIZE, 1,
	    "Entropy request");
	if (error) {
		aprint_error_dev(sc->sc_dev, "can't alloc virtqueue: %d\n",
				 error);
		goto vio_failed;
	}

	sc->sc_vq.vq_done = viornd_vq_done;
	virtio_start_vq_intr(vsc, &sc->sc_vq);
	rndsource_setcb(&sc->sc_rndsource, viornd_get, sc);
	rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev),
			  RND_TYPE_RNG,
			  RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB);
	viornd_get(VIORND_BUFSIZE, sc);
	return;
vio_failed:
	bus_dmamap_unload(vsc->sc_dmat, sc->sc_dmamap);
load_failed:
	bus_dmamap_destroy(vsc->sc_dmat, sc->sc_dmamap);
create_failed:
	bus_dmamem_unmap(vsc->sc_dmat, sc->sc_buf, VIORND_BUFSIZE);
map_failed:
	bus_dmamem_free(vsc->sc_dmat, segs, nsegs);
alloc_failed:
	vsc->sc_child = (void *)1;	/* XXX bare constant 1 */
	return;
}
Ejemplo n.º 16
0
static	void	
sackbc_attach(device_t parent, device_t self, void *aux)
{
	struct sackbc_softc *sc = device_private(self);
	struct sacc_softc *psc = device_private(parent);
	struct sa1111_attach_args *aa = (struct sa1111_attach_args *)aux;
	device_t child;
	uint32_t tmp, clock_bit;
	int intr, slot;

	switch (aa->sa_addr) {
	case SACC_KBD0: clock_bit = (1<<6); intr = 21; break;
	case SACC_KBD1: clock_bit = (1<<5); intr = 18; break;
	default:
		return;
	}

	if (aa->sa_size <= 0)
		aa->sa_size = SACCKBD_SIZE;
	if (aa->sa_intr == SACCCF_INTR_DEFAULT)
		aa->sa_intr = intr;

	sc->dev = self;
	sc->iot = psc->sc_iot;
	if (bus_space_subregion(psc->sc_iot, psc->sc_ioh,
	    aa->sa_addr, aa->sa_size, &sc->ioh)) {
		aprint_normal(": can't map subregion\n");
		return;
	}

	/* enable clock for PS/2 kbd or mouse */
	tmp = bus_space_read_4(psc->sc_iot, psc->sc_ioh, SACCSC_SKPCR);
	bus_space_write_4(psc->sc_iot, psc->sc_ioh, SACCSC_SKPCR,
	    tmp | clock_bit);

	sc->ih_rx = NULL;
	sc->intr = aa->sa_intr;
	sc->polling = 0;

	tmp = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_CR);
	bus_space_write_4(sc->iot, sc->ioh, SACCKBD_CR, tmp | KBDCR_ENA);

	/* XXX: this is necessary to get keyboard working. but I don't know why */
	bus_space_write_4(sc->iot, sc->ioh, SACCKBD_CLKDIV, 2);

	tmp = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_STAT);
	if ((tmp & KBDSTAT_ENA) == 0) {
		printf("??? can't enable KBD controller\n");
		return;
	}

	printf("\n");

	sc->pt = pckbport_attach(sc, &sackbc_ops);

	/*
	 * Although there is no such thing as SLOT for SA-1111 kbd
	 * controller, pckbd and pms drivers require it.
	 */
	for (slot = PCKBPORT_KBD_SLOT; slot <= PCKBPORT_AUX_SLOT; ++slot) {
		child = pckbport_attach_slot(self, sc->pt, slot);

		if (child == NULL)
			continue;
		sc->slot = slot;
		rnd_attach_source(&sc->rnd_source, device_xname(child),
		    RND_TYPE_TTY, RND_FLAG_DEFAULT|RND_FLAG_ESTIMATE_VALUE);
		/* only one of KBD_SLOT or AUX_SLOT is used. */
		break;			
	}
}
Ejemplo n.º 17
0
/*
 * Attach the interface. Allocate softc structures, do ifmedia
 * setup and ethernet/BPF attach.
 */
void
rtk_attach(struct rtk_softc *sc)
{
	device_t self = sc->sc_dev;
	struct ifnet *ifp;
	struct rtk_tx_desc *txd;
	uint16_t val;
	uint8_t eaddr[ETHER_ADDR_LEN];
	int error;
	int i, addr_len;

	callout_init(&sc->rtk_tick_ch, 0);

	/*
	 * Check EEPROM type 9346 or 9356.
	 */
	if (rtk_read_eeprom(sc, RTK_EE_ID, RTK_EEADDR_LEN1) == 0x8129)
		addr_len = RTK_EEADDR_LEN1;
	else
		addr_len = RTK_EEADDR_LEN0;

	/*
	 * Get station address.
	 */
	val = rtk_read_eeprom(sc, RTK_EE_EADDR0, addr_len);
	eaddr[0] = val & 0xff;
	eaddr[1] = val >> 8;
	val = rtk_read_eeprom(sc, RTK_EE_EADDR1, addr_len);
	eaddr[2] = val & 0xff;
	eaddr[3] = val >> 8;
	val = rtk_read_eeprom(sc, RTK_EE_EADDR2, addr_len);
	eaddr[4] = val & 0xff;
	eaddr[5] = val >> 8;

	if ((error = bus_dmamem_alloc(sc->sc_dmat,
	    RTK_RXBUFLEN + 16, PAGE_SIZE, 0, &sc->sc_dmaseg, 1, &sc->sc_dmanseg,
	    BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(self,
		    "can't allocate recv buffer, error = %d\n", error);
		goto fail_0;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dmaseg, sc->sc_dmanseg,
	    RTK_RXBUFLEN + 16, (void **)&sc->rtk_rx_buf,
	    BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
		aprint_error_dev(self,
		    "can't map recv buffer, error = %d\n", error);
		goto fail_1;
	}

	if ((error = bus_dmamap_create(sc->sc_dmat,
	    RTK_RXBUFLEN + 16, 1, RTK_RXBUFLEN + 16, 0, BUS_DMA_NOWAIT,
	    &sc->recv_dmamap)) != 0) {
		aprint_error_dev(self,
		    "can't create recv buffer DMA map, error = %d\n", error);
		goto fail_2;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->recv_dmamap,
	    sc->rtk_rx_buf, RTK_RXBUFLEN + 16,
	    NULL, BUS_DMA_READ|BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(self,
		    "can't load recv buffer DMA map, error = %d\n", error);
		goto fail_3;
	}

	for (i = 0; i < RTK_TX_LIST_CNT; i++) {
		txd = &sc->rtk_tx_descs[i];
		if ((error = bus_dmamap_create(sc->sc_dmat,
		    MCLBYTES, 1, MCLBYTES, 0, BUS_DMA_NOWAIT,
		    &txd->txd_dmamap)) != 0) {
			aprint_error_dev(self,
			    "can't create snd buffer DMA map, error = %d\n",
			    error);
			goto fail_4;
		}
		txd->txd_txaddr = RTK_TXADDR0 + (i * 4);
		txd->txd_txstat = RTK_TXSTAT0 + (i * 4);
	}
	SIMPLEQ_INIT(&sc->rtk_tx_free);
	SIMPLEQ_INIT(&sc->rtk_tx_dirty);

	/*
	 * From this point forward, the attachment cannot fail. A failure
	 * before this releases all resources thar may have been
	 * allocated.
	 */
	sc->sc_flags |= RTK_ATTACHED;

	/* Reset the adapter. */
	rtk_reset(sc);

	aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(eaddr));

	ifp = &sc->ethercom.ec_if;
	ifp->if_softc = sc;
	strcpy(ifp->if_xname, device_xname(self));
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = rtk_ioctl;
	ifp->if_start = rtk_start;
	ifp->if_watchdog = rtk_watchdog;
	ifp->if_init = rtk_init;
	ifp->if_stop = rtk_stop;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * Do ifmedia setup.
	 */
	sc->mii.mii_ifp = ifp;
	sc->mii.mii_readreg = rtk_phy_readreg;
	sc->mii.mii_writereg = rtk_phy_writereg;
	sc->mii.mii_statchg = rtk_phy_statchg;
	sc->ethercom.ec_mii = &sc->mii;
	ifmedia_init(&sc->mii.mii_media, IFM_IMASK, ether_mediachange,
	    ether_mediastatus);
	mii_attach(self, &sc->mii, 0xffffffff,
	    MII_PHY_ANY, MII_OFFSET_ANY, 0);

	/* Choose a default media. */
	if (LIST_FIRST(&sc->mii.mii_phys) == NULL) {
		ifmedia_add(&sc->mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
		ifmedia_set(&sc->mii.mii_media, IFM_ETHER|IFM_NONE);
	} else {
		ifmedia_set(&sc->mii.mii_media, IFM_ETHER|IFM_AUTO);
	}

	/*
	 * Call MI attach routines.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, eaddr);

	rnd_attach_source(&sc->rnd_source, device_xname(self),
	    RND_TYPE_NET, RND_FLAG_DEFAULT);

	return;
 fail_4:
	for (i = 0; i < RTK_TX_LIST_CNT; i++) {
		txd = &sc->rtk_tx_descs[i];
		if (txd->txd_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat, txd->txd_dmamap);
	}
 fail_3:
	bus_dmamap_destroy(sc->sc_dmat, sc->recv_dmamap);
 fail_2:
	bus_dmamem_unmap(sc->sc_dmat, sc->rtk_rx_buf,
	    RTK_RXBUFLEN + 16);
 fail_1:
	bus_dmamem_free(sc->sc_dmat, &sc->sc_dmaseg, sc->sc_dmanseg);
 fail_0:
	return;
}
Ejemplo n.º 18
0
void
smap_attach(struct device *parent, struct device *self, void *aux)
{
	struct spd_attach_args *spa = aux;
	struct smap_softc *sc = (void *)self;
	struct emac3_softc *emac3 = &sc->emac3;
	struct ifnet *ifp = &sc->ethercom.ec_if;
	struct mii_data *mii = &emac3->mii;
	void *txbuf, *rxbuf;
	u_int16_t r;

#ifdef SMAP_DEBUG
	__sc = sc;
#endif

	printf(": %s\n", spa->spa_product_name);

	/* SPD EEPROM */
	if (smap_get_eaddr(sc, emac3->eaddr) != 0)
		return;

	printf("%s: Ethernet address %s\n", DEVNAME,
	    ether_sprintf(emac3->eaddr));

	/* disable interrupts */
	r = _reg_read_2(SPD_INTR_ENABLE_REG16);
	r &= ~(SPD_INTR_RXEND | SPD_INTR_TXEND | SPD_INTR_RXDNV |
	    SPD_INTR_EMAC3);
	_reg_write_2(SPD_INTR_ENABLE_REG16, r);
	emac3_intr_disable();

	/* clear pending interrupts */
	_reg_write_2(SPD_INTR_CLEAR_REG16, SPD_INTR_RXEND | SPD_INTR_TXEND |
	    SPD_INTR_RXDNV);
	emac3_intr_clear();

	/* buffer descriptor mode */
	_reg_write_1(SMAP_DESC_MODE_REG8, 0);

	if (smap_fifo_init(sc) != 0)
		return;

	if (emac3_init(&sc->emac3) != 0)
		return;
	emac3_intr_disable();
	emac3_disable();

	smap_desc_init(sc);

	/* allocate temporary buffer */
	txbuf = malloc(ETHER_MAX_LEN - ETHER_CRC_LEN + SMAP_FIFO_ALIGN + 16,
	    M_DEVBUF, M_NOWAIT);
	if (txbuf == NULL) {
		printf("%s: no memory.\n", DEVNAME);		
		return;
	}

	rxbuf = malloc(ETHER_MAX_LEN + SMAP_FIFO_ALIGN + 16,
	    M_DEVBUF, M_NOWAIT);
	if (rxbuf == NULL) {
		printf("%s: no memory.\n", DEVNAME);
		free(txbuf, M_DEVBUF);
		return;
	}

	sc->tx_buf = (u_int32_t *)ROUND16((vaddr_t)txbuf);
	sc->rx_buf = (u_int32_t *)ROUND16((vaddr_t)rxbuf);

	/* 
	 * setup MI layer 
	 */
	strcpy(ifp->if_xname, DEVNAME);
	ifp->if_softc	= sc;
	ifp->if_start	= smap_start;
	ifp->if_ioctl	= smap_ioctl;
	ifp->if_init	= smap_init;
	ifp->if_stop	= smap_stop;
	ifp->if_watchdog= smap_watchdog;
	ifp->if_flags	= IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |
	    IFF_MULTICAST;
	IFQ_SET_READY(&ifp->if_snd);

	/* ifmedia setup. */
	mii->mii_ifp		= ifp;
	mii->mii_readreg	= emac3_phy_readreg;
	mii->mii_writereg	= emac3_phy_writereg;
	mii->mii_statchg	= emac3_phy_statchg;
	sc->ethercom.ec_mii = mii;
	ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
	mii_attach(&emac3->dev, mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);
	    
	/* Choose a default media. */
	if (LIST_FIRST(&mii->mii_phys) == NULL) {
		ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
		ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_NONE);
	} else {
		ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO);
	}

	if_attach(ifp);
	ether_ifattach(ifp, emac3->eaddr);
	
	spd_intr_establish(SPD_NIC, smap_intr, sc);

#if NRND > 0
	rnd_attach_source(&sc->rnd_source, DEVNAME,
	    RND_TYPE_NET, RND_FLAG_DEFAULT);
#endif
}
Ejemplo n.º 19
0
void
uhidev_attach(device_t parent, device_t self, void *aux)
{
	struct uhidev_softc *sc = device_private(self);
	struct usbif_attach_arg *uiaa = aux;
	struct usbd_interface *iface = uiaa->uiaa_iface;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	struct uhidev_attach_arg uha;
	device_t dev;
	struct uhidev *csc;
	int maxinpktsize, size, nrepid, repid, repsz;
	int *repsizes;
	int i;
	void *desc;
	const void *descptr;
	usbd_status err;
	char *devinfop;
	int locs[UHIDBUSCF_NLOCS];

	sc->sc_dev = self;
	sc->sc_udev = uiaa->uiaa_device;
	sc->sc_iface = iface;

	aprint_naive("\n");
	aprint_normal("\n");

	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);

	id = usbd_get_interface_descriptor(iface);

	devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0);
	aprint_normal_dev(self, "%s, iclass %d/%d\n",
	       devinfop, id->bInterfaceClass, id->bInterfaceSubClass);
	usbd_devinfo_free(devinfop);

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");

	(void)usbd_set_idle(iface, 0, 0);
#if 0

	if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_NO_SET_PROTO) == 0 &&
	    id->bInterfaceSubClass != UISUBCLASS_BOOT)
		(void)usbd_set_protocol(iface, 1);
#endif

	maxinpktsize = 0;
	sc->sc_iep_addr = sc->sc_oep_addr = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(iface, i);
		if (ed == NULL) {
			aprint_error_dev(self,
			    "could not read endpoint descriptor\n");
			sc->sc_dying = 1;
			return;
		}

		DPRINTFN(10,("uhidev_attach: bLength=%d bDescriptorType=%d "
		    "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
		    " bInterval=%d\n",
		    ed->bLength, ed->bDescriptorType,
		    ed->bEndpointAddress & UE_ADDR,
		    UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
		    ed->bmAttributes & UE_XFERTYPE,
		    UGETW(ed->wMaxPacketSize), ed->bInterval));

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
			maxinpktsize = UGETW(ed->wMaxPacketSize);
			sc->sc_iep_addr = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
			sc->sc_oep_addr = ed->bEndpointAddress;
		} else {
			aprint_verbose_dev(self, "endpoint %d: ignored\n", i);
		}
	}

	/*
	 * Check that we found an input interrupt endpoint. The output interrupt
	 * endpoint is optional
	 */
	if (sc->sc_iep_addr == -1) {
		aprint_error_dev(self, "no input interrupt endpoint\n");
		sc->sc_dying = 1;
		return;
	}

	/* XXX need to extend this */
	descptr = NULL;
	if (uiaa->uiaa_vendor == USB_VENDOR_WACOM) {
		static uByte reportbuf[] = {2, 2, 2};

		/* The report descriptor for the Wacom Graphire is broken. */
		switch (uiaa->uiaa_product) {
		case USB_PRODUCT_WACOM_GRAPHIRE:
		case USB_PRODUCT_WACOM_GRAPHIRE2:
		case USB_PRODUCT_WACOM_GRAPHIRE3_4X5:
		case USB_PRODUCT_WACOM_GRAPHIRE3_6X8:
		case USB_PRODUCT_WACOM_GRAPHIRE4_4X5: /* The 6x8 too? */
			/*
			 * The Graphire3 needs 0x0202 to be written to
			 * feature report ID 2 before it'll start
			 * returning digitizer data.
			 */
			usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 2,
			    &reportbuf, sizeof(reportbuf));

			size = sizeof(uhid_graphire3_4x5_report_descr);
			descptr = uhid_graphire3_4x5_report_descr;
			break;
		default:
			/* Keep descriptor */
			break;
		}
	}
	if (USBIF_IS_XINPUT(uiaa)) {
		size = sizeof(uhid_xinput_report_descr);
		descptr = uhid_xinput_report_descr;
	}
	if (USBIF_IS_X1INPUT(uiaa)) {
		sc->sc_flags |= UHIDEV_F_XB1;
		size = sizeof(uhid_x1input_report_descr);
		descptr = uhid_x1input_report_descr;
	}

	if (descptr) {
		desc = kmem_alloc(size, KM_SLEEP);
		if (desc == NULL)
			err = USBD_NOMEM;
		else {
			err = USBD_NORMAL_COMPLETION;
			memcpy(desc, descptr, size);
		}
	} else {
		desc = NULL;
		err = usbd_read_report_desc(uiaa->uiaa_iface, &desc, &size);
	}
	if (err) {
		aprint_error_dev(self, "no report descriptor\n");
		sc->sc_dying = 1;
		return;
	}

	if (uiaa->uiaa_vendor == USB_VENDOR_HOSIDEN &&
	    uiaa->uiaa_product == USB_PRODUCT_HOSIDEN_PPP) {
		static uByte reportbuf[] = { 1 };
		/*
		 *  This device was sold by Konami with its ParaParaParadise
		 *  game for PlayStation2.  It needs to be "turned on"
		 *  before it will send any reports.
		 */

		usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 0,
		    &reportbuf, sizeof(reportbuf));
	}

	if (uiaa->uiaa_vendor == USB_VENDOR_LOGITECH &&
	    uiaa->uiaa_product == USB_PRODUCT_LOGITECH_CBT44 && size == 0xb1) {
		uint8_t *data = desc;
		/*
		 * This device has a odd USAGE_MINIMUM value that would
		 * cause the multimedia keys to have their usage number
		 * shifted up one usage.  Adjust so the usages are sane.
		 */

		if (data[0x56] == 0x19 && data[0x57] == 0x01 &&
		    data[0x58] == 0x2a && data[0x59] == 0x8c)
			data[0x57] = 0x00;
	}

	/*
	 * Enable the Six Axis and DualShock 3 controllers.
	 * See http://ps3.jim.sh/sixaxis/usb/
	 */
	if (uiaa->uiaa_vendor == USB_VENDOR_SONY &&
	    uiaa->uiaa_product == USB_PRODUCT_SONY_PS3CONTROLLER) {
		usb_device_request_t req;
		char data[17];
		int actlen;

		req.bmRequestType = UT_READ_CLASS_INTERFACE;
		req.bRequest = 1;
		USETW(req.wValue, 0x3f2);
		USETW(req.wIndex, 0);
		USETW(req.wLength, sizeof(data));

		usbd_do_request_flags(sc->sc_udev, &req, data,
			USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
	}

	sc->sc_repdesc = desc;
	sc->sc_repdesc_size = size;

	uha.uiaa = uiaa;
	nrepid = uhidev_maxrepid(desc, size);
	if (nrepid < 0)
		return;
	if (nrepid > 0)
		aprint_normal_dev(self, "%d report ids\n", nrepid);
	nrepid++;
	repsizes = kmem_alloc(nrepid * sizeof(*repsizes), KM_SLEEP);
	if (repsizes == NULL)
		goto nomem;
	sc->sc_subdevs = kmem_zalloc(nrepid * sizeof(device_t),
	    KM_SLEEP);
	if (sc->sc_subdevs == NULL) {
		kmem_free(repsizes, nrepid * sizeof(*repsizes));
nomem:
		aprint_error_dev(self, "no memory\n");
		return;
	}

	/* Just request max packet size for the interrupt pipe */
	sc->sc_isize = maxinpktsize;
	sc->sc_nrepid = nrepid;

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);

	for (repid = 0; repid < nrepid; repid++) {
		repsz = hid_report_size(desc, size, hid_input, repid);
		DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz));
		repsizes[repid] = repsz;
	}

	DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));

	uha.parent = sc;
	for (repid = 0; repid < nrepid; repid++) {
		DPRINTF(("uhidev_match: try repid=%d\n", repid));
		if (hid_report_size(desc, size, hid_input, repid) == 0 &&
		    hid_report_size(desc, size, hid_output, repid) == 0 &&
		    hid_report_size(desc, size, hid_feature, repid) == 0) {
			;	/* already NULL in sc->sc_subdevs[repid] */
		} else {
			uha.reportid = repid;
			locs[UHIDBUSCF_REPORTID] = repid;

			dev = config_found_sm_loc(self,
				"uhidbus", locs, &uha,
				uhidevprint, config_stdsubmatch);
			sc->sc_subdevs[repid] = dev;
			if (dev != NULL) {
				csc = device_private(dev);
				csc->sc_in_rep_size = repsizes[repid];
#ifdef DIAGNOSTIC
				DPRINTF(("uhidev_match: repid=%d dev=%p\n",
					 repid, dev));
				if (csc->sc_intr == NULL) {
					kmem_free(repsizes,
					    nrepid * sizeof(*repsizes));
					aprint_error_dev(self,
					    "sc_intr == NULL\n");
					return;
				}
#endif
				rnd_attach_source(&csc->rnd_source,
						  device_xname(dev),
						  RND_TYPE_TTY,
						  RND_FLAG_DEFAULT);
			}
		}
	}
	kmem_free(repsizes, nrepid * sizeof(*repsizes));

	return;
}
Ejemplo n.º 20
0
/* Attach */
void
url_attach(device_t parent, device_t self, void *aux)
{
	struct url_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usbd_interface_handle iface;
	usbd_status err;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	struct ifnet *ifp;
	struct mii_data *mii;
	u_char eaddr[ETHER_ADDR_LEN];
	int i, s;

	sc->sc_dev = self;

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

	/* Move the device into the configured state. */
	err = usbd_set_config_no(dev, URL_CONFIG_NO, 1);
	if (err) {
		aprint_error_dev(self, "failed to set configuration"
		    ", err=%s\n", usbd_errstr(err));
		goto bad;
	}

	usb_init_task(&sc->sc_tick_task, url_tick_task, sc, 0);
	rw_init(&sc->sc_mii_rwlock);
	usb_init_task(&sc->sc_stop_task, (void (*)(void *))url_stop_task, sc, 0);

	/* get control interface */
	err = usbd_device2interface_handle(dev, URL_IFACE_INDEX, &iface);
	if (err) {
		aprint_error_dev(self, "failed to get interface, err=%s\n",
		       usbd_errstr(err));
		goto bad;
	}

	sc->sc_udev = dev;
	sc->sc_ctl_iface = iface;
	sc->sc_flags = url_lookup(uaa->vendor, uaa->product)->url_flags;

	/* get interface descriptor */
	id = usbd_get_interface_descriptor(sc->sc_ctl_iface);

	/* find endpoints */
	sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
		if (ed == NULL) {
			aprint_error_dev(self,
			    "couldn't get endpoint %d\n", i);
			goto bad;
		}
		if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
		    UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
			sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */
		else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
			 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
			sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */
		else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
			 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
			sc->sc_intrin_no = ed->bEndpointAddress; /* Status */
	}

	if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 ||
	    sc->sc_intrin_no == -1) {
		aprint_error_dev(self, "missing endpoint\n");
		goto bad;
	}

	s = splnet();

	/* reset the adapter */
	url_reset(sc);

	/* Get Ethernet Address */
	err = url_mem(sc, URL_CMD_READMEM, URL_IDR0, (void *)eaddr,
		      ETHER_ADDR_LEN);
	if (err) {
		aprint_error_dev(self, "read MAC address failed\n");
		splx(s);
		goto bad;
	}

	/* Print Ethernet Address */
	aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(eaddr));

	/* initialize interface information */
	ifp = GET_IFP(sc);
	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;
	strncpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_start = url_start;
	ifp->if_ioctl = url_ioctl;
	ifp->if_watchdog = url_watchdog;
	ifp->if_init = url_init;
	ifp->if_stop = url_stop;

	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * Do ifmedia setup.
	 */
	mii = &sc->sc_mii;
	mii->mii_ifp = ifp;
	mii->mii_readreg = url_int_miibus_readreg;
	mii->mii_writereg = url_int_miibus_writereg;
#if 0
	if (sc->sc_flags & URL_EXT_PHY) {
		mii->mii_readreg = url_ext_miibus_readreg;
		mii->mii_writereg = url_ext_miibus_writereg;
	}
#endif
	mii->mii_statchg = url_miibus_statchg;
	mii->mii_flags = MIIF_AUTOTSLEEP;
	sc->sc_ec.ec_mii = mii;
	ifmedia_init(&mii->mii_media, 0,
		     url_ifmedia_change, url_ifmedia_status);
	mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
	if (LIST_FIRST(&mii->mii_phys) == NULL) {
		ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
	} else
		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);

	/* attach the interface */
	if_attach(ifp);
	ether_ifattach(ifp, eaddr);

	rnd_attach_source(&sc->rnd_source, device_xname(self),
	    RND_TYPE_NET, 0);

	callout_init(&sc->sc_stat_ch, 0);
	sc->sc_attached = 1;
	splx(s);

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, sc->sc_dev);

	return;

 bad:
	sc->sc_dying = 1;
	return;
}
Ejemplo n.º 21
0
void
sbscn_attach_channel(struct sbscn_softc *sc, int chan, int intr)
{
	struct sbscn_channel *ch = &sc->sc_channels[chan];
	u_long chan_addr;
	struct tty *tp;

	ch->ch_sc = sc;
	ch->ch_num = chan;

	chan_addr = sc->sc_addr + (0x100 * chan);
	ch->ch_base = (void *)MIPS_PHYS_TO_KSEG1(chan_addr);
	ch->ch_isr_base =
	    (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x220 + (0x20 * chan));
	ch->ch_imr_base =
	    (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x230 + (0x20 * chan));
#ifdef XXXCGDnotyet
	ch->ch_inchg_base =
	    (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x2d0 + (0x10 * chan));
#endif

	ch->ch_i_dcd = ch->ch_i_dcd_pin = 0 /* XXXCGD */;
	ch->ch_i_cts = ch->ch_i_cts_pin = 0 /* XXXCGD */;
	ch->ch_i_dsr = ch->ch_i_dsr_pin = 0 /* XXXCGD */;
	ch->ch_i_ri = ch->ch_i_ri_pin = 0 /* XXXCGD */;
	ch->ch_i_mask =
	    ch->ch_i_dcd | ch->ch_i_cts | ch->ch_i_dsr | ch->ch_i_ri;
	ch->ch_o_dtr = ch->ch_o_dtr_pin = 0 /* XXXCGD */;
	ch->ch_o_rts = ch->ch_o_rts_pin = 0 /* XXXCGD */;
	ch->ch_o_mask = ch->ch_o_dtr | ch->ch_o_rts;

	ch->ch_intrhand = cpu_intr_establish(intr, IPL_SERIAL, sbscn_intr, ch);
	callout_init(&ch->ch_diag_callout, 0);

	/* Disable interrupts before configuring the device. */
	ch->ch_imr = 0;
	WRITE_REG(ch->ch_imr_base, ch->ch_imr);

	if (sbscn_cons_present &&
	    sbscn_cons_addr == chan_addr && sbscn_cons_chan == chan) {
		sbscn_cons_attached = 1;

		/* Make sure the console is always "hardwired". */
		delay(1000);			/* wait for output to finish */
		SET(ch->ch_hwflags, SBSCN_HW_CONSOLE);
		SET(ch->ch_swflags, TIOCFLAG_SOFTCAR);
	}

	tp = tty_alloc();
	tp->t_oproc = sbscn_start;
	tp->t_param = sbscn_param;
	tp->t_hwiflow = sbscn_hwiflow;

	ch->ch_tty = tp;
	ch->ch_rbuf = malloc(sbscn_rbuf_size << 1, M_DEVBUF, M_NOWAIT);
	if (ch->ch_rbuf == NULL) {
		aprint_error_dev(sc->sc_dev,
		    "channel %d: unable to allocate ring buffer\n",
		    chan);
		return;
	}
	ch->ch_ebuf = ch->ch_rbuf + (sbscn_rbuf_size << 1);

	tty_attach(tp);

	if (ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&sbscn_cdevsw);

		cn_tab->cn_dev = makedev(maj,
		    (device_unit(sc->sc_dev) << 1) + chan);

		aprint_normal_dev(sc->sc_dev, "channel %d: %s\n",
		    chan, "console");
	}

#ifdef KGDB
	/*
	 * Allow kgdb to "take over" this port.  If this is
	 * the kgdb device, it has exclusive use.
	 */
	if (sbscn_kgdb_present &&
	    sbscn_kgdb_addr == chan_addr && sbscn_kgdb_chan == chan) {
		sbscn_kgdb_attached = 1;

		SET(sc->sc_hwflags, SBSCN_HW_KGDB);
		aprint_normal_dev(sc->sc_dev, "channel %d: %s\n",
		    chan, "kgdb");
	}
#endif

	ch->ch_si = softint_establish(SOFTINT_SERIAL, sbscn_soft, ch);

#ifdef RND_SBSCN
	rnd_attach_source(&ch->ch_rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, 0);
#endif

	sbscn_config(ch);

	SET(ch->ch_hwflags, SBSCN_HW_DEV_OK);
}
Ejemplo n.º 22
0
static void
bce_attach(device_t parent, device_t self, void *aux)
{
	struct bce_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	const struct bce_product *bp;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char     *intrstr = NULL;
	uint32_t	command;
	pcireg_t	memtype, pmode;
	bus_addr_t	memaddr;
	bus_size_t	memsize;
	void		*kva;
	bus_dma_segment_t seg;
	int             error, i, pmreg, rseg;
	struct ifnet   *ifp;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->bce_dev = self;

	bp = bce_lookup(pa);
	KASSERT(bp != NULL);

	sc->bce_pa = *pa;

	/* BCM440x can only address 30 bits (1GB) */
	if (bus_dmatag_subregion(pa->pa_dmat, 0, (1 << 30),
	    &(sc->bce_dmatag), BUS_DMA_NOWAIT) != 0) {
		aprint_error_dev(self,
		    "WARNING: failed to restrict dma range,"
		    " falling back to parent bus dma range\n");
		sc->bce_dmatag = pa->pa_dmat;
	}

	 aprint_naive(": Ethernet controller\n");
	 aprint_normal(": %s\n", bp->bp_name);

	/*
	 * Map control/status registers.
	 */
	command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	command |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
	command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);

	if (!(command & PCI_COMMAND_MEM_ENABLE)) {
		aprint_error_dev(self, "failed to enable memory mapping!\n");
		return;
	}
	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BCE_PCI_BAR0);
	switch (memtype) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		if (pci_mapreg_map(pa, BCE_PCI_BAR0, memtype, 0, &sc->bce_btag,
		    &sc->bce_bhandle, &memaddr, &memsize) == 0)
			break;
	default:
		aprint_error_dev(self, "unable to find mem space\n");
		return;
	}

	/* Get it out of power save mode if needed. */
	if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, NULL)) {
		pmode = pci_conf_read(pc, pa->pa_tag, pmreg + 4) & 0x3;
		if (pmode == 3) {
			/*
			 * The card has lost all configuration data in
			 * this state, so punt.
			 */
			aprint_error_dev(self,
			    "unable to wake up from power state D3\n");
			return;
		}
		if (pmode != 0) {
			aprint_normal_dev(self,
			    "waking up from power state D%d\n", pmode);
			pci_conf_write(pc, pa->pa_tag, pmreg + 4, 0);
		}
	}
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));

	sc->bce_intrhand = pci_intr_establish(pc, ih, IPL_NET, bce_intr, sc);

	if (sc->bce_intrhand == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt\n");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	/* reset the chip */
	bce_reset(sc);

	/*
	 * Allocate DMA-safe memory for ring descriptors.
	 * The receive, and transmit rings can not share the same
	 * 4k space, however both are allocated at once here.
	 */
	/*
	 * XXX PAGE_SIZE is wasteful; we only need 1KB + 1KB, but
	 * due to the limition above. ??
	 */
	if ((error = bus_dmamem_alloc(sc->bce_dmatag,
	    2 * PAGE_SIZE, PAGE_SIZE, 2 * PAGE_SIZE,
	    &seg, 1, &rseg, BUS_DMA_NOWAIT))) {
		aprint_error_dev(self,
		    "unable to alloc space for ring descriptors, error = %d\n",
		    error);
		return;
	}
	/* map ring space to kernel */
	if ((error = bus_dmamem_map(sc->bce_dmatag, &seg, rseg,
	    2 * PAGE_SIZE, &kva, BUS_DMA_NOWAIT))) {
		aprint_error_dev(self,
		    "unable to map DMA buffers, error = %d\n", error);
		bus_dmamem_free(sc->bce_dmatag, &seg, rseg);
		return;
	}
	/* create a dma map for the ring */
	if ((error = bus_dmamap_create(sc->bce_dmatag,
	    2 * PAGE_SIZE, 1, 2 * PAGE_SIZE, 0, BUS_DMA_NOWAIT,
	    &sc->bce_ring_map))) {
		aprint_error_dev(self,
		    "unable to create ring DMA map, error = %d\n", error);
		bus_dmamem_unmap(sc->bce_dmatag, kva, 2 * PAGE_SIZE);
		bus_dmamem_free(sc->bce_dmatag, &seg, rseg);
		return;
	}
	/* connect the ring space to the dma map */
	if (bus_dmamap_load(sc->bce_dmatag, sc->bce_ring_map, kva,
	    2 * PAGE_SIZE, NULL, BUS_DMA_NOWAIT)) {
		bus_dmamap_destroy(sc->bce_dmatag, sc->bce_ring_map);
		bus_dmamem_unmap(sc->bce_dmatag, kva, 2 * PAGE_SIZE);
		bus_dmamem_free(sc->bce_dmatag, &seg, rseg);
		return;
	}
	/* save the ring space in softc */
	sc->bce_rx_ring = (struct bce_dma_slot *) kva;
	sc->bce_tx_ring = (struct bce_dma_slot *) ((char *)kva + PAGE_SIZE);

	/* Create the transmit buffer DMA maps. */
	for (i = 0; i < BCE_NTXDESC; i++) {
		if ((error = bus_dmamap_create(sc->bce_dmatag, MCLBYTES,
		    BCE_NTXFRAGS, MCLBYTES, 0, 0, &sc->bce_cdata.bce_tx_map[i])) != 0) {
			aprint_error_dev(self,
			    "unable to create tx DMA map, error = %d\n", error);
		}
		sc->bce_cdata.bce_tx_chain[i] = NULL;
	}

	/* Create the receive buffer DMA maps. */
	for (i = 0; i < BCE_NRXDESC; i++) {
		if ((error = bus_dmamap_create(sc->bce_dmatag, MCLBYTES, 1,
		    MCLBYTES, 0, 0, &sc->bce_cdata.bce_rx_map[i])) != 0) {
			aprint_error_dev(self,
			    "unable to create rx DMA map, error = %d\n", error);
		}
		sc->bce_cdata.bce_rx_chain[i] = NULL;
	}

	/* Set up ifnet structure */
	ifp = &sc->ethercom.ec_if;
	strcpy(ifp->if_xname, device_xname(self));
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = bce_ioctl;
	ifp->if_start = bce_start;
	ifp->if_watchdog = bce_watchdog;
	ifp->if_init = bce_init;
	ifp->if_stop = bce_stop;
	IFQ_SET_READY(&ifp->if_snd);

	/* Initialize our media structures and probe the MII. */

	sc->bce_mii.mii_ifp = ifp;
	sc->bce_mii.mii_readreg = bce_mii_read;
	sc->bce_mii.mii_writereg = bce_mii_write;
	sc->bce_mii.mii_statchg = bce_statchg;

	sc->ethercom.ec_mii = &sc->bce_mii;
	ifmedia_init(&sc->bce_mii.mii_media, 0, ether_mediachange,
	    ether_mediastatus);
	mii_attach(sc->bce_dev, &sc->bce_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, MIIF_FORCEANEG|MIIF_DOPAUSE);
	if (LIST_FIRST(&sc->bce_mii.mii_phys) == NULL) {
		ifmedia_add(&sc->bce_mii.mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
		ifmedia_set(&sc->bce_mii.mii_media, IFM_ETHER | IFM_NONE);
	} else
		ifmedia_set(&sc->bce_mii.mii_media, IFM_ETHER | IFM_AUTO);
	/* get the phy */
	sc->bce_phy = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
	    BCE_MAGIC_PHY) & 0x1f;
	/*
	 * Enable activity led.
	 * XXX This should be in a phy driver, but not currently.
	 */
	bce_mii_write(sc->bce_dev, 1, 26,	 /* MAGIC */
	    bce_mii_read(sc->bce_dev, 1, 26) & 0x7fff);	 /* MAGIC */
	/* enable traffic meter led mode */
	bce_mii_write(sc->bce_dev, 1, 27,	 /* MAGIC */
	    bce_mii_read(sc->bce_dev, 1, 27) | (1 << 6));	 /* MAGIC */

	/* Attach the interface */
	if_attach(ifp);
	sc->enaddr[0] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
	    BCE_MAGIC_ENET0);
	sc->enaddr[1] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
	    BCE_MAGIC_ENET1);
	sc->enaddr[2] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
	    BCE_MAGIC_ENET2);
	sc->enaddr[3] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
	    BCE_MAGIC_ENET3);
	sc->enaddr[4] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
	    BCE_MAGIC_ENET4);
	sc->enaddr[5] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
	    BCE_MAGIC_ENET5);
	aprint_normal_dev(self, "Ethernet address %s\n",
	    ether_sprintf(sc->enaddr));
	ether_ifattach(ifp, sc->enaddr);
	rnd_attach_source(&sc->rnd_source, device_xname(self),
	    RND_TYPE_NET, 0);
	callout_init(&sc->bce_timeout, 0);

	if (pmf_device_register(self, NULL, bce_resume))
		pmf_class_network_register(self, ifp);
	else
		aprint_error_dev(self, "couldn't establish power handler\n");
}
Ejemplo n.º 23
0
/*
 * Attach the interface. Allocate softc structures, do
 * setup and ethernet/BPF attach.
 */
void
kue_attach(device_t parent, device_t self, void *aux)
{
	struct kue_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	char			*devinfop;
	int			s;
	struct ifnet		*ifp;
	usbd_device_handle	dev = uaa->device;
	usbd_interface_handle	iface;
	usbd_status		err;
	usb_interface_descriptor_t	*id;
	usb_endpoint_descriptor_t	*ed;
	int			i;

	DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev));

	sc->kue_dev = self;

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

	err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1);
	if (err) {
		aprint_error_dev(self, "failed to set configuration"
		    ", err=%s\n", usbd_errstr(err));
		return;
	}

	sc->kue_udev = dev;
	sc->kue_product = uaa->product;
	sc->kue_vendor = uaa->vendor;

	/* Load the firmware into the NIC. */
	if (kue_load_fw(sc)) {
		aprint_error_dev(self, "loading firmware failed\n");
		return;
	}

	err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &iface);
	if (err) {
		aprint_error_dev(self, "getting interface handle failed\n");
		return;
	}

	sc->kue_iface = iface;
	id = usbd_get_interface_descriptor(iface);

	/* Find endpoints. */
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(iface, i);
		if (ed == NULL) {
			aprint_error_dev(self, "couldn't get ep %d\n", i);
			return;
		}
		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress;
		}
	}

	if (sc->kue_ed[KUE_ENDPT_RX] == 0 || sc->kue_ed[KUE_ENDPT_TX] == 0) {
		aprint_error_dev(self, "missing endpoint\n");
		return;
	}

	/* Read ethernet descriptor */
	err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
	    0, &sc->kue_desc, sizeof(sc->kue_desc));
	if (err) {
		aprint_error_dev(self, "could not read Ethernet descriptor\n");
		return;
	}

	sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
	    M_USBDEV, M_NOWAIT);
	if (sc->kue_mcfilters == NULL) {
		aprint_error_dev(self,
		    "no memory for multicast filter buffer\n");
		return;
	}

	s = splnet();

	/*
	 * A KLSI chip was detected. Inform the world.
	 */
	aprint_normal_dev(self, "Ethernet address %s\n",
	    ether_sprintf(sc->kue_desc.kue_macaddr));

	/* Initialize interface info.*/
	ifp = GET_IFP(sc);
	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = kue_ioctl;
	ifp->if_start = kue_start;
	ifp->if_watchdog = kue_watchdog;
	strncpy(ifp->if_xname, device_xname(sc->kue_dev), IFNAMSIZ);

	IFQ_SET_READY(&ifp->if_snd);

	/* Attach the interface. */
	if_attach(ifp);
	ether_ifattach(ifp, sc->kue_desc.kue_macaddr);
	rnd_attach_source(&sc->rnd_source, device_xname(sc->kue_dev),
	    RND_TYPE_NET, RND_FLAG_DEFAULT);

	sc->kue_attached = true;
	splx(s);

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->kue_udev,
			   sc->kue_dev);

	return;
}
Ejemplo n.º 24
0
void
sscom_attach_subr(struct sscom_softc *sc)
{
	int unit = sc->sc_unit;
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;
	struct tty *tp;

	callout_init(&sc->sc_diag_callout, 0);
#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK)
	sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SERIAL);
#endif

	sc->sc_ucon = UCON_RXINT_ENABLE|UCON_TXINT_ENABLE;

	/*
	 * set default for modem control hook
	 */
	if (sc->sc_set_modem_control == NULL)
		sc->sc_set_modem_control = sscom_set_modem_control;
	if (sc->sc_read_modem_status == NULL)
		sc->sc_read_modem_status = sscom_read_modem_status;

	/* Disable interrupts before configuring the device. */
	KASSERT(sc->sc_change_txrx_interrupts != NULL);
	KASSERT(sc->sc_clear_interrupts != NULL);
	sscom_disable_txrxint(sc);

#ifdef KGDB
	/*
	 * Allow kgdb to "take over" this port.  If this is
	 * the kgdb device, it has exclusive use.
	 */
	if (unit == sscom_kgdb_unit) {
		SET(sc->sc_hwflags, SSCOM_HW_KGDB);
		sc->sc_ucon = UCON_DEBUGPORT;
	}
#endif

	if (unit == sscomconsunit) {
		uint32_t stat;
		int timo;

		sscomconsattached = 1;
		sscomconstag = iot;
		sscomconsioh = ioh;

		/* wait for this transmission to complete */
		timo = 1500000;
		do {
			stat = bus_space_read_4(iot, ioh, SSCOM_UTRSTAT);
		} while ((stat & UTRSTAT_TXEMPTY) == 0 && --timo > 0);

		/* Make sure the console is always "hardwired". */
		SET(sc->sc_hwflags, SSCOM_HW_CONSOLE);
		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);

		sc->sc_ucon = UCON_DEBUGPORT;
	}

	/* set RX/TX trigger to half values */
	bus_space_write_4(iot, ioh, SSCOM_UFCON,
	    __SHIFTIN(4, UFCON_TXTRIGGER) |
	    __SHIFTIN(4, UFCON_RXTRIGGER) |
	     UFCON_FIFO_ENABLE | 
	     UFCON_TXFIFO_RESET|
	     UFCON_RXFIFO_RESET);
	/* tx/rx fifo reset are auto-cleared */

	bus_space_write_4(iot, ioh, SSCOM_UCON, sc->sc_ucon);

#ifdef KGDB
	if (ISSET(sc->sc_hwflags, SSCOM_HW_KGDB)) {
		sscom_kgdb_attached = 1;
		printf("%s: kgdb\n", device_xname(sc->sc_dev));
		sscom_enable_debugport(sc);
		return;
	}
#endif

	tp = tty_alloc();
	tp->t_oproc = sscomstart;
	tp->t_param = sscomparam;
	tp->t_hwiflow = sscomhwiflow;

	sc->sc_tty = tp;
	sc->sc_rbuf = malloc(sscom_rbuf_size << 1, M_DEVBUF, M_NOWAIT);
	sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
	sc->sc_rbavail = sscom_rbuf_size;
	if (sc->sc_rbuf == NULL) {
		printf("%s: unable to allocate ring buffer\n",
		    device_xname(sc->sc_dev));
		return;
	}
	sc->sc_ebuf = sc->sc_rbuf + (sscom_rbuf_size << 1);

	tty_attach(tp);

	if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&sscom_cdevsw);

		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));

		printf("%s: console (major=%d)\n", device_xname(sc->sc_dev), maj);
	}


	sc->sc_si = softint_establish(SOFTINT_SERIAL, sscomsoft, sc);

#ifdef RND_COM
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, RND_FLAG_DEFAULT);
#endif

	/* if there are no enable/disable functions, assume the device
	   is always enabled */

	if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE))
		sscom_enable_debugport(sc);
	else 
		sscom_disable_txrxint(sc);

	SET(sc->sc_hwflags, SSCOM_HW_DEV_OK);
}
Ejemplo n.º 25
0
void
sacom_attach_subr(struct sacom_softc *sc)
{
    bus_addr_t iobase = sc->sc_baseaddr;
    bus_space_tag_t iot = sc->sc_iot;
    struct tty *tp;

    /* XXX Do we need to disable interrupts here? */

    if (iot == sacomconstag && iobase == sacomconsaddr) {
        sacomconsattached = 1;
        sc->sc_speed = SACOMSPEED(sacomconsrate);

        /* Make sure the console is always "hardwired". */
        delay(10000);			/* wait for output to finish */
        SET(sc->sc_hwflags, COM_HW_CONSOLE);
        SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
    }

    tp = ttymalloc();
    tp->t_oproc = sacomstart;
    tp->t_param = sacomparam;
    tp->t_hwiflow = sacomhwiflow;

    sc->sc_tty = tp;
    sc->sc_rbuf = malloc(SACOM_RING_SIZE << 1, M_DEVBUF, M_NOWAIT);
    sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
    sc->sc_rbavail = SACOM_RING_SIZE;
    if (sc->sc_rbuf == NULL) {
        printf("%s: unable to allocate ring buffer\n",
               sc->sc_dev.dv_xname);
        return;
    }
    sc->sc_ebuf = sc->sc_rbuf + (SACOM_RING_SIZE << 1);
    sc->sc_tbc = 0;

    tty_attach(tp);

    if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
        int maj;

        /* locate the major number */
        maj = cdevsw_lookup_major(&sacom_cdevsw);

        cn_tab->cn_dev = makedev(maj, device_unit(&sc->sc_dev));

        delay(10000); /* XXX */
        printf("%s: console\n", sc->sc_dev.dv_xname);
        delay(10000); /* XXX */
    }


    sc->sc_si = softint_establish(SOFTINT_SERIAL, sacomsoft, sc);

#if NRND > 0 && defined(RND_COM)
    rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
                      RND_TYPE_TTY, 0);
#endif

    /* if there are no enable/disable functions, assume the device
       is always enabled */
    if (!sc->enable)
        sc->enabled = 1;

    sacom_config(sc);

    SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
Ejemplo n.º 26
0
static void
at91dbgu_attach(device_t parent, device_t self, void *aux)
{
	struct at91dbgu_softc *sc = device_private(self);
	struct at91bus_attach_args *sa = aux;
	struct tty *tp;

	printf("\n");

	sc->sc_dev = self;
	bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh);
	sc->sc_iot = sa->sa_iot;
	sc->sc_hwbase = sa->sa_addr;

	DBGUREG(DBGU_IDR) = -1;
	at91_intr_establish(sa->sa_pid, IPL_SERIAL, INTR_HIGH_LEVEL, dbgu_intr, sc);
	DBGU_INIT(AT91_MSTCLK, 115200U);

	if (sc->sc_iot == dbgu_cn_sc.sc_iot
	    && sc->sc_hwbase == dbgu_cn_sc.sc_hwbase) {
		dbgu_cn_sc.sc_attached = 1;
		/* Make sure the console is always "hardwired". */
		delay(10000);	/* wait for output to finish */
		SET(sc->sc_hwflags, COM_HW_CONSOLE);
		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
		SET(sc->sc_ier, DBGU_INT_RXRDY);
		DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; // @@@@@
	}

	tp = tty_alloc();
	tp->t_oproc = at91dbgu_start;
	tp->t_param = at91dbgu_param;
	tp->t_hwiflow = at91dbgu_hwiflow;

	sc->sc_tty = tp;
	sc->sc_rbuf = malloc(AT91DBGU_RING_SIZE << 1, M_DEVBUF, M_NOWAIT);
	sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
	sc->sc_rbavail = AT91DBGU_RING_SIZE;
	if (sc->sc_rbuf == NULL) {
		printf("%s: unable to allocate ring buffer\n",
		    device_xname(sc->sc_dev));
		return;
	}
	sc->sc_ebuf = sc->sc_rbuf + (AT91DBGU_RING_SIZE << 1);
	sc->sc_tbc = 0;

	tty_attach(tp);

	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&at91dbgu_cdevsw);

		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));

		aprint_normal("%s: console (maj %u min %u cn_dev %#"PRIx64")\n",
		    device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev),
		    cn_tab->cn_dev);
	}

	sc->sc_si = softint_establish(SOFTINT_SERIAL, at91dbgu_soft, sc);

#ifdef RND_COM
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, 0);
#endif

	/* if there are no enable/disable functions, assume the device
	   is always enabled */
	if (!sc->enable)
		sc->enabled = 1;

	/* XXX configure register */
	/* xxx_config(sc) */

	SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
Ejemplo n.º 27
0
/*
 * Attach the interface to the kernel data structures.  By the time this is
 * called, we know that the card exists at the given I/O address.  We still
 * assume that the IRQ given is correct.
 */
void
elattach(device_t parent, device_t self, void *aux)
{
	struct el_softc *sc = device_private(self);
	struct isa_attach_args *ia = aux;
	bus_space_tag_t iot = ia->ia_iot;
	bus_space_handle_t ioh;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	u_int8_t myaddr[ETHER_ADDR_LEN];
	u_int8_t i;

	sc->sc_dev = self;

	printf("\n");

	DPRINTF(("Attaching %s...\n", device_xname(sc->sc_dev)));

	/* Map i/o space. */
	if (bus_space_map(iot, ia->ia_io[0].ir_addr, 16, 0, &ioh)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	sc->sc_iot = iot;
	sc->sc_ioh = ioh;

	/* Reset the board. */
	bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
	delay(5);
	bus_space_write_1(iot, ioh, EL_AC, 0);

	/* Now read the address. */
	for (i = 0; i < ETHER_ADDR_LEN; i++) {
		bus_space_write_1(iot, ioh, EL_GPBL, i);
		myaddr[i] = bus_space_read_1(iot, ioh, EL_EAW);
	}

	/* Stop the board. */
	elstop(sc);

	/* Initialize ifnet structure. */
	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_start = elstart;
	ifp->if_ioctl = elioctl;
	ifp->if_watchdog = elwatchdog;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
	IFQ_SET_READY(&ifp->if_snd);

	/* Now we can attach the interface. */
	DPRINTF(("Attaching interface...\n"));
	if_attach(ifp);
	ether_ifattach(ifp, myaddr);

	/* Print out some information for the user. */
	printf("%s: address %s\n", device_xname(self), ether_sprintf(myaddr));

	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
	    IST_EDGE, IPL_NET, elintr, sc);

	DPRINTF(("Attaching to random...\n"));
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_NET, RND_FLAG_DEFAULT);

	DPRINTF(("elattach() finished.\n"));
}
Ejemplo n.º 28
0
void
at91usart_attach_subr(struct at91usart_softc *sc, struct at91bus_attach_args *sa)
{
	struct tty *tp;
	int err;

	printf("\n");

	if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh))
		panic("%s: Cannot map registers", device_xname(sc->sc_dev));

	sc->sc_iot = sa->sa_iot;
	sc->sc_hwbase = sa->sa_addr;
	sc->sc_dmat = sa->sa_dmat;
	sc->sc_pid = sa->sa_pid;

	/* allocate fifos */
	err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_rx_fifo, AT91USART_RING_SIZE, BUS_DMA_READ | BUS_DMA_STREAMING);
	if (err)
		panic("%s: cannot allocate rx fifo", device_xname(sc->sc_dev));

	err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_tx_fifo, AT91USART_RING_SIZE, BUS_DMA_WRITE | BUS_DMA_STREAMING);
	if (err)
		panic("%s: cannot allocate tx fifo", device_xname(sc->sc_dev));

	/* initialize uart */
	at91_peripheral_clock(sc->sc_pid, 1);

	at91usart_writereg(sc, US_IDR, -1);
	at91usart_writereg(sc, US_RTOR, 12);	// 12-bit timeout
	at91usart_writereg(sc, US_PDC + PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
	at91_intr_establish(sa->sa_pid, IPL_TTY, INTR_HIGH_LEVEL, at91usart_intr, sc);
	USART_INIT(sc, 115200U);

#ifdef	NOTYET
	if (sc->sc_iot == usart_cn_sc.sc_iot
	    && sc->sc_hwbase == usart_cn_sc.sc_hwbase) {
		usart_cn_sc.sc_attached = 1;
		/* Make sure the console is always "hardwired". */
		delay(10000);	/* wait for output to finish */
		SET(sc->sc_hwflags, COM_HW_CONSOLE);
		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
		SET(sc->sc_ier, USART_INT_RXRDY);
		USARTREG(USART_IER) = USART_INT_RXRDY; // @@@@@
	}
#endif	// NOTYET

	tp = tty_alloc();
	tp->t_oproc = at91usart_start;
	tp->t_param = at91usart_param;
	tp->t_hwiflow = at91usart_hwiflow;

	sc->sc_tty = tp;

	tty_attach(tp);

#if	NOTYET
	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&at91usart_cdevsw);

		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));

		aprint_normal("%s: console (maj %u  min %u  cn_dev %u)\n",
		    device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev),
		    cn_tab->cn_dev);
	}
#endif	/* NOTYET */

	sc->sc_si = softint_establish(SOFTINT_SERIAL, at91usart_soft, sc);

#ifdef RND_COM
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, RND_FLAG_DEFAULT);
#endif

	/* if there are no enable/disable functions, assume the device
	   is always enabled */
	if (!sc->enable)
		sc->enabled = 1;

	/* XXX configure register */
	/* xxx_config(sc) */

	SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
Ejemplo n.º 29
0
static void
arckbd_attach(device_t parent, device_t self, void *aux)
{
	struct arckbd_softc *sc = device_private(self);
	struct ioc_attach_args *ioc = aux;
	bus_space_tag_t bst;
	bus_space_handle_t bsh;
	struct wskbddev_attach_args wskbdargs;
	struct wsmousedev_attach_args wsmouseargs;

	bst = sc->sc_bst = ioc->ioc_fast_t;
	bsh = sc->sc_bsh = ioc->ioc_fast_h; 

	sc->sc_dev = self;
	evcnt_attach_dynamic(&sc->sc_rev, EVCNT_TYPE_INTR, NULL,
	    device_xname(sc->sc_dev), "rx intr");
	sc->sc_rirq = irq_establish(IOC_IRQ_SRX, IPL_TTY, arckbd_rint, self,
	    &sc->sc_rev);
	aprint_verbose("\n%s: interrupting at %s (rx)", device_xname(self),
	    irq_string(sc->sc_rirq));

	evcnt_attach_dynamic(&sc->sc_xev, EVCNT_TYPE_INTR, NULL,
	    device_xname(sc->sc_dev), "tx intr");
	sc->sc_xirq = irq_establish(IOC_IRQ_STX, IPL_TTY, arckbd_xint, self,
	    &sc->sc_xev);
	irq_disable(sc->sc_xirq);
	aprint_verbose(" and %s (tx)", irq_string(sc->sc_xirq));

       	/* Initialisation of IOC KART per IOC Data Sheet section 6.2.3. */

       	/* Set up IOC counter 3 */
	/* k_BAUD = 1/((latch+1)*16) MHz */
	ioc_counter_start(parent, 3, 62500 / ARCKBD_BAUD - 1);

	/* Read from Rx register and discard. */
	(void)bus_space_read_1(bst, bsh, 0);

	/* Kick the keyboard into life */
	arckbd_send(self, ARCKBD_HRST, AS_HRST, 0);

	sc->sc_mapdata = arckbd_mapdata_default;
	sc->sc_mapdata.layout = KB_UK; /* Reasonable default */

	/* Attach the wskbd console */
	arckbd_cnattach(self);

	aprint_normal("\n");

	rnd_attach_source(&sc->sc_rnd_source, device_xname(self),
	    RND_TYPE_TTY, 0);

	wskbdargs.console = 1; /* XXX FIXME */
	wskbdargs.keymap = &sc->sc_mapdata;
	wskbdargs.accessops = &arckbd_accessops;
	wskbdargs.accesscookie = sc;
	sc->sc_wskbddev = config_found_ia(self, "wskbddev", &wskbdargs, NULL);

	wsmouseargs.accessops = &arcmouse_accessops;
	wsmouseargs.accesscookie = sc;
	sc->sc_wsmousedev =
	    config_found_ia(self, "wsmousedev", &wsmouseargs, NULL);
}