Exemplo n.º 1
0
static int
ed_pci_attach(device_t dev)
{
        struct	ed_softc *sc = device_get_softc(dev);
        int	flags = 0;
        int	error;

        error = ed_probe_Novell(dev, PCIR_MAPS, flags);
        if (error)
                return (error);

        error = ed_alloc_irq(dev, 0, RF_SHAREABLE);
        if (error) {
                ed_release_resources(dev);
                return (error);
        }

	error = ed_attach(dev);
	if (error == 0) {
		struct ifnet *ifp = &sc->arpcom.ac_if;

		error = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE,
				       edintr, sc, &sc->irq_handle,
				       ifp->if_serializer);
		if (error) {
			ed_pci_detach(dev);
		} else {
			ifp->if_cpuid = rman_get_cpuid(sc->irq_res);
			KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);
		}
	} else {
                ed_release_resources(dev);
	}
	return (error);
}
Exemplo n.º 2
0
/*
 * Currently this uses the really grody interface from kern/kern_intr.c
 * (which really doesn't belong in kern/anything.c).  Eventually, all of
 * the code in kern_intr.c and machdep_intr.c should get moved here, since
 * this is going to be the official interface.
 */
static int
nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
		 int flags, void (*ihand)(void *), void *arg,
		 void **cookiep, lwkt_serialize_t serializer)
{
	int	error, icflags;

	/* somebody tried to setup an irq that failed to allocate! */
	if (irq == NULL)
		panic("nexus_setup_intr: NULL irq resource!");

	*cookiep = 0;
	icflags = flags;
	if ((irq->r_flags & RF_SHAREABLE) == 0)
		icflags |= INTR_EXCL;

	/*
	 * We depend here on rman_activate_resource() being idempotent.
	 */
	error = rman_activate_resource(irq);
	if (error)
		return (error);

	/*
	 * XXX cast the interrupt handler function to an inthand2_t.  The
	 * difference is that an additional frame argument is passed which
	 * we do not currently want to expose the BUS subsystem to.
	 */
	*cookiep = register_int(irq->r_start, (inthand2_t *)ihand, arg,
				device_get_nameunit(child), serializer,
				icflags, rman_get_cpuid(irq));
	if (*cookiep == NULL)
		error = EINVAL;
	return (error);
}
Exemplo n.º 3
0
static int
an_attach_isa(device_t dev)
{
	struct an_softc *sc = device_get_softc(dev);
	struct ifnet *ifp = &sc->arpcom.ac_if;
	int flags = device_get_flags(dev);
	int error;

	an_alloc_port(dev, sc->port_rid, 1);
	an_alloc_irq(dev, sc->irq_rid, 0);

	sc->an_bhandle = rman_get_bushandle(sc->port_res);
	sc->an_btag = rman_get_bustag(sc->port_res);

	error = an_attach(sc, dev, flags);
	if (error)
		goto fail;

	error = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE,
			       an_intr, sc, &sc->irq_handle, 
			       sc->arpcom.ac_if.if_serializer);
	if (error) {
		ether_ifdetach(&sc->arpcom.ac_if);
		ifmedia_removeall(&sc->an_ifmedia);
		goto fail;
	}

	ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->irq_res));

	return (0);

fail:
	an_release_resources(dev);
	return(error);
}
Exemplo n.º 4
0
static int
nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
{
	if (ih) {
		unregister_int(ih, rman_get_cpuid(r));
		return (0);
	}
	return(-1);
}
Exemplo n.º 5
0
static int
ex_pccard_attach(device_t dev)
{
	struct ex_softc *	sc = device_get_softc(dev);
	struct ifnet *		ifp = &sc->arpcom.ac_if;
	int			error = 0;
	int			i;
	uint8_t			sum;
	const uint8_t	*	ether_addr;

	sc->dev = dev;
	sc->ioport_rid = 0;
	sc->irq_rid = 0;

	if ((error = ex_alloc_resources(dev)) != 0) {
		device_printf(dev, "ex_alloc_resources() failed!\n");
		goto bad;
	}

	/*
	 * Fill in several fields of the softc structure:
	 *	- I/O base address.
	 *	- Hardware Ethernet address.
	 *	- IRQ number.
	 */
	sc->iobase = rman_get_start(sc->ioport);
	sc->irq_no = rman_get_start(sc->irq);

	ether_addr = pccard_get_ether(dev);
	for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
		sum |= ether_addr[i];
	if (sum)
		bcopy(ether_addr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);

	if ((error = ex_attach(dev)) != 0) {
		device_printf(dev, "ex_attach() failed!\n");
		goto bad;
	}

	error = bus_setup_intr(dev, sc->irq, INTR_MPSAFE,
				ex_intr, (void *)sc, &sc->ih, 
				ifp->if_serializer);
	if (error) {
		device_printf(dev, "bus_setup_intr() failed!\n");
		goto bad;
	}

	ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->irq));

	return(0);
bad:
	ex_release_resources(dev);
	return (error);
}
Exemplo n.º 6
0
static int
an_pccard_attach(device_t dev)
{
	struct an_softc *sc = device_get_softc(dev);
	struct ifnet *ifp = &sc->arpcom.ac_if;
	int flags = device_get_flags(dev);
	int error;

	an_alloc_port(dev, sc->port_rid, AN_IOSIZ);
	an_alloc_irq(dev, sc->irq_rid, 0);

	sc->an_bhandle = rman_get_bushandle(sc->port_res);
	sc->an_btag = rman_get_bustag(sc->port_res);

	error = an_attach(sc, dev, flags);
	if (error)
		goto fail;

	/*
	 * Must setup the interrupt after the an_attach to prevent racing.
	 */
	error = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE,
			       an_intr, sc, &sc->irq_handle,
			       sc->arpcom.ac_if.if_serializer);
	if (error) {
		ether_ifdetach(&sc->arpcom.ac_if);
		ifmedia_removeall(&sc->an_ifmedia);
		goto fail;
	}

	ifp->if_cpuid = rman_get_cpuid(sc->irq_res);
	KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);

	return 0;

fail:
	an_release_resources(dev);
	return (error);
}
Exemplo n.º 7
0
static int
sbsh_attach(device_t dev)
{
	struct sbsh_softc	*sc;
	struct ifnet		*ifp;
	int			unit, error = 0, rid;

	sc = device_get_softc(dev);
	unit = device_get_unit(dev);

	rid = PCIR_MAPS + 4;
	sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
					0, ~0, 4096, RF_ACTIVE);

	if (sc->mem_res == NULL) {
		kprintf ("sbsh%d: couldn't map memory\n", unit);
		error = ENXIO;
		goto fail;
	}

	rid = 0;
	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);

	if (sc->irq_res == NULL) {
		kprintf("sbsh%d: couldn't map interrupt\n", unit);
		error = ENXIO;
		goto fail;
	}

	sc->mem_base = rman_get_virtual(sc->mem_res);
	init_card(sc);
	/* generate ethernet MAC address */
	*(u_int32_t *)sc->arpcom.ac_enaddr = htonl(0x00ff0192);
	read_random_unlimited(sc->arpcom.ac_enaddr + 4, 2);

	ifp = &sc->arpcom.ac_if;
	ifp->if_softc = sc;
	if_initname(ifp, "sbsh", unit);
	ifp->if_mtu = ETHERMTU;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = sbsh_ioctl;
	ifp->if_start = sbsh_start;
	ifp->if_watchdog = sbsh_watchdog;
	ifp->if_init = sbsh_init;
	ifp->if_baudrate = 4600000;
	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
	ifq_set_ready(&ifp->if_snd);

	ether_ifattach(ifp, sc->arpcom.ac_enaddr, NULL);

	ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->irq_res));

	error = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE,
				sbsh_intr, sc, &sc->intr_hand, 
				ifp->if_serializer);
	if (error) {
		ether_ifdetach(ifp);
		kprintf("sbsh%d: couldn't set up irq\n", unit);
		goto fail;
	}

	return(0);

fail:
	sbsh_detach(dev);
	return (error);
}
Exemplo n.º 8
0
/* Attach the interface. Allocate softc structures */
static int
sln_attach(device_t dev)
{
	struct sln_softc *sc = device_get_softc(dev);
	struct ifnet *ifp = &sc->arpcom.ac_if;
	unsigned char eaddr[ETHER_ADDR_LEN];
	int rid;
	int error = 0;

	if_initname(ifp, device_get_name(dev), device_get_unit(dev));

	/* TODO: power state change */

	pci_enable_busmaster(dev);

	rid = SL_RID;
	sc->sln_res = bus_alloc_resource_any(dev, SL_RES, &rid, RF_ACTIVE);
	if (sc->sln_res == NULL) {
		device_printf(dev, "couldn't map ports/memory\n");
		error = ENXIO;
		goto fail;
	}
	sc->sln_bustag = rman_get_bustag(sc->sln_res);
	sc->sln_bushandle = rman_get_bushandle(sc->sln_res);

	/* alloc pci irq */
	rid = 0;
	sc->sln_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sln_irq == NULL) {
		device_printf(dev, "couldn't map interrupt\n");
		bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res);
		error = ENXIO;
		goto fail;
	}

	/* Get MAC address */
	((uint32_t *)(&eaddr))[0] = be32toh(SLN_READ_4(sc, SL_MAC_ADDR0));
	((uint16_t *)(&eaddr))[2] = be16toh(SLN_READ_4(sc, SL_MAC_ADDR1));

	/* alloc rx buffer space */
	sc->sln_bufdata.sln_rx_buf = contigmalloc(SL_RX_BUFLEN,
	    M_DEVBUF, M_WAITOK, 0, 0xffffffff, PAGE_SIZE, 0);
	if (sc->sln_bufdata.sln_rx_buf == NULL) {
		device_printf(dev, "no memory for rx buffers!\n");
		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq);
		bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res);
		error = ENXIO;
		goto fail;
	}
	callout_init(&sc->sln_state);

	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_init = sln_init;
	ifp->if_start = sln_tx;
	ifp->if_ioctl = sln_ioctl;
	ifp->if_watchdog = sln_watchdog;
	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
	ifq_set_ready(&ifp->if_snd);

	/* initial media */
	ifmedia_init(&sc->ifmedia, 0, sln_media_upd, sln_media_stat);

	/* supported media types */
	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);
	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_HDX, 0, NULL);
	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL);
	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_HDX, 0, NULL);
	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);

	/* Choose a default media. */
	ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO);

	ether_ifattach(ifp, eaddr, NULL);

	error = bus_setup_intr(dev, sc->sln_irq, INTR_MPSAFE, sln_interrupt, sc,
			       &sc->sln_intrhand, ifp->if_serializer);
	if (error) {
		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq);
		bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res);
		ether_ifdetach(ifp);
		device_printf(dev, "couldn't set up irq\n");
		goto fail;
	}

	ifp->if_cpuid = rman_get_cpuid(sc->sln_irq);
	KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);

	return 0;
fail:
	return error;
}
Exemplo n.º 9
0
static int
le_isa_attach(device_t dev)
{
	struct le_isa_softc *lesc;
	struct lance_softc *sc;
	bus_size_t macstart, rap, rdp;
	int error, i, macstride;

	lesc = device_get_softc(dev);
	sc = &lesc->sc_am7990.lsc;

	lesc->sc_rrid = 0;
	switch (ISA_PNP_PROBE(device_get_parent(dev), dev, le_isa_ids)) {
	case 0:
		lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
		    &lesc->sc_rrid, RF_ACTIVE);
		rap = PCNET_RAP;
		rdp = PCNET_RDP;
		macstart = 0;
		macstride = 1;
		break;
	case ENOENT:
		for (i = 0; i < NELEM(le_isa_params); i++) {
			if (le_isa_probe_legacy(dev, &le_isa_params[i]) == 0) {
				lesc->sc_rres = bus_alloc_resource(dev,
				    SYS_RES_IOPORT, &lesc->sc_rrid, 0, ~0,
				    le_isa_params[i].iosize, RF_ACTIVE);
				rap = le_isa_params[i].rap;
				rdp = le_isa_params[i].rdp;
				macstart = le_isa_params[i].macstart;
				macstride = le_isa_params[i].macstride;
				goto found;
			}
		}
		/* FALLTHROUGH */
	case ENXIO:
	default:
		device_printf(dev, "cannot determine chip\n");
		error = ENXIO;
		goto fail_mtx;
	}

 found:
	if (lesc->sc_rres == NULL) {
		device_printf(dev, "cannot allocate registers\n");
		error = ENXIO;
		goto fail_mtx;
	}
	lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
	lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
	lesc->sc_rap = rap;
	lesc->sc_rdp = rdp;

	lesc->sc_drid = 0;
	if ((lesc->sc_dres = bus_alloc_resource_any(dev, SYS_RES_DRQ,
	    &lesc->sc_drid, RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate DMA channel\n");
		error = ENXIO;
		goto fail_rres;
	}

	lesc->sc_irid = 0;
	if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate interrupt\n");
		error = ENXIO;
		goto fail_dres;
	}

	error = bus_dma_tag_create(
	    NULL,			/* parent */
	    1, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_24BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
	    0,				/* nsegments */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_pdmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate parent DMA tag\n");
		goto fail_ires;
	}

	sc->sc_memsize = LE_ISA_MEMSIZE;
	/*
	 * For Am79C90, Am79C961 and Am79C961A the init block must be 2-byte
	 * aligned and the ring descriptors must be 8-byte aligned.
	 */
	error = bus_dma_tag_create(
	    lesc->sc_pdmat,		/* parent */
	    8, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_24BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    sc->sc_memsize,		/* maxsize */
	    1,				/* nsegments */
	    sc->sc_memsize,		/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_dmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate buffer DMA tag\n");
		goto fail_pdtag;
	}

	error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
	    BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
	if (error != 0) {
		device_printf(dev, "cannot allocate DMA buffer memory\n");
		goto fail_dtag;
	}

	sc->sc_addr = 0;
	error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
	    sc->sc_memsize, le_isa_dma_callback, sc, 0);
	if (error != 0 || sc->sc_addr == 0) {
                device_printf(dev, "cannot load DMA buffer map\n");
		goto fail_dmem;
	}

	isa_dmacascade(rman_get_start(lesc->sc_dres));

	sc->sc_flags = 0;
	sc->sc_conf3 = 0;

	/*
	 * Extract the physical MAC address from the ROM.
	 */
	for (i = 0; i < sizeof(sc->sc_enaddr); i++)
		sc->sc_enaddr[i] =  bus_space_read_1(lesc->sc_regt,
		    lesc->sc_regh, macstart + i * macstride);

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = le_isa_rdcsr;
	sc->sc_wrcsr = le_isa_wrcsr;
	sc->sc_hwreset = NULL;
	sc->sc_hwinit = NULL;
	sc->sc_hwintr = NULL;
	sc->sc_nocarrier = NULL;
	sc->sc_mediachange = NULL;
	sc->sc_mediastatus = NULL;
	sc->sc_supmedia = NULL;

	error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
	    device_get_unit(dev));
	if (error != 0) {
		device_printf(dev, "cannot attach Am7990\n");
		goto fail_dmap;
	}

	ifq_set_cpuid(&sc->ifp->if_snd, rman_get_cpuid(lesc->sc_ires));

	error = bus_setup_intr(dev, lesc->sc_ires, INTR_MPSAFE,
	    am7990_intr, sc, &lesc->sc_ih, sc->ifp->if_serializer);
	if (error != 0) {
		device_printf(dev, "cannot set up interrupt\n");
		goto fail_am7990;
	}

	return (0);

 fail_am7990:
	am7990_detach(&lesc->sc_am7990);
 fail_dmap:
	bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
 fail_dmem:
	bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
 fail_dtag:
	bus_dma_tag_destroy(lesc->sc_dmat);
 fail_pdtag:
	bus_dma_tag_destroy(lesc->sc_pdmat);
 fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
 fail_dres:
	bus_release_resource(dev, SYS_RES_DRQ, lesc->sc_drid, lesc->sc_dres);
 fail_rres:
	bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
 fail_mtx:
	return (error);
}
Exemplo n.º 10
0
/*
 * Attach the interface. Allocate softc structures, do ifmedia
 * setup and ethernet/BPF attach.
 */
static int
ndis_attach_pccard(device_t dev)
{
	struct ndis_softc	*sc;
	int			unit, error = 0, rid;
	struct ndis_pccard_type	*t;
	int			devidx = 0;
	const char		*prodstr, *vendstr;
	struct drvdb_ent	*db;

	wlan_serialize_enter();
	sc = device_get_softc(dev);
	unit = device_get_unit(dev);
	sc->ndis_dev = dev;

	db = windrv_match((matchfuncptr)ndis_devcompare, dev);
	if (db == NULL) {
		wlan_serialize_exit();
		return (ENXIO);
	}
	sc->ndis_dobj = db->windrv_object;
	sc->ndis_regvals = db->windrv_regvals;
	resource_list_init(&sc->ndis_rl);

	sc->ndis_io_rid = 0;
	sc->ndis_res_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
	    &sc->ndis_io_rid, RF_ACTIVE);
	if (sc->ndis_res_io == NULL) {
		device_printf(dev,
		    "couldn't map iospace\n");
		error = ENXIO;
		goto fail;
	}
	sc->ndis_rescnt++;
	resource_list_add(&sc->ndis_rl, SYS_RES_IOPORT, rid,
	    rman_get_start(sc->ndis_res_io), rman_get_end(sc->ndis_res_io),
	    rman_get_size(sc->ndis_res_io), -1);

	rid = 0;
	sc->ndis_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->ndis_irq == NULL) {
		device_printf(dev,
		    "couldn't map interrupt\n");
		error = ENXIO;
		goto fail;
	}
	sc->ndis_rescnt++;
	resource_list_add(&sc->ndis_rl, SYS_RES_IRQ, rid,
	    rman_get_start(sc->ndis_irq), rman_get_start(sc->ndis_irq), 1,
	    rman_get_cpuid(sc->ndis_irq));

	sc->ndis_iftype = PCMCIABus;

	/* Figure out exactly which device we matched. */

	t = db->windrv_devlist;

	prodstr = pccard_get_product_str(dev);
	vendstr = pccard_get_vendor_str(dev);

	while(t->ndis_name != NULL) {
		if (strcasecmp(vendstr, t->ndis_vid) == 0 &&
		    strcasecmp(prodstr, t->ndis_did) == 0)
			break;
		t++;
		devidx++;
	}

	sc->ndis_devidx = devidx;

	error = ndis_attach(dev);

fail:
	wlan_serialize_exit();
	return(error);
}
Exemplo n.º 11
0
static int
le_pci_attach(device_t dev)
{
	struct le_pci_softc *lesc;
	struct lance_softc *sc;
	int error, i;

	lesc = device_get_softc(dev);
	sc = &lesc->sc_am79900.lsc;

	pci_enable_busmaster(dev);
	pci_enable_io(dev, PCIM_CMD_PORTEN);

	lesc->sc_rrid = PCIR_BAR(0);
	lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
	    &lesc->sc_rrid, RF_ACTIVE);
	if (lesc->sc_rres == NULL) {
		device_printf(dev, "cannot allocate registers\n");
		error = ENXIO;
		goto fail_mtx;
	}
	lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
	lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);

	lesc->sc_irid = 0;
	if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate interrupt\n");
		error = ENXIO;
		goto fail_rres;
	}

	error = bus_dma_tag_create(
	    NULL,			/* parent */
	    1, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
	    0,				/* nsegments */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_pdmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate parent DMA tag\n");
		goto fail_ires;
	}

	sc->sc_memsize = PCNET_MEMSIZE;
	/*
	 * For Am79C970A, Am79C971 and Am79C978 the init block must be 2-byte
	 * aligned and the ring descriptors must be 16-byte aligned when using
	 * a 32-bit software style.
	 */
	error = bus_dma_tag_create(
	    lesc->sc_pdmat,		/* parent */
	    16, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    sc->sc_memsize,		/* maxsize */
	    1,				/* nsegments */
	    sc->sc_memsize,		/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_dmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate buffer DMA tag\n");
		goto fail_pdtag;
	}

	error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
	    BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
	if (error != 0) {
		device_printf(dev, "cannot allocate DMA buffer memory\n");
		goto fail_dtag;
	}

	sc->sc_addr = 0;
	error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
	    sc->sc_memsize, le_pci_dma_callback, sc, 0);
	if (error != 0 || sc->sc_addr == 0) {
                device_printf(dev, "cannot load DMA buffer map\n");
		goto fail_dmem;
	}

	sc->sc_flags = LE_BSWAP;
	sc->sc_conf3 = 0;

	sc->sc_mediastatus = NULL;
	switch (pci_get_device(dev)) {
	case AMD_PCNET_HOME:
		sc->sc_mediachange = le_pci_mediachange;
		sc->sc_supmedia = le_home_supmedia;
		sc->sc_nsupmedia = sizeof(le_home_supmedia) / sizeof(int);
		sc->sc_defaultmedia = le_home_supmedia[0];
		break;
	default:
		sc->sc_mediachange = le_pci_mediachange;
		sc->sc_supmedia = le_pci_supmedia;
		sc->sc_nsupmedia = sizeof(le_pci_supmedia) / sizeof(int);
		sc->sc_defaultmedia = le_pci_supmedia[0];
	}

	/*
	 * Extract the physical MAC address from the ROM.
	 */
	for (i = 0; i < sizeof(sc->sc_enaddr); i++)
		sc->sc_enaddr[i] =
		    bus_space_read_1(lesc->sc_regt, lesc->sc_regh, i);

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = le_pci_rdcsr;
	sc->sc_wrcsr = le_pci_wrcsr;
	sc->sc_hwreset = le_pci_hwreset;
	sc->sc_hwinit = NULL;
	sc->sc_hwintr = NULL;
	sc->sc_nocarrier = NULL;

	error = am79900_config(&lesc->sc_am79900, device_get_name(dev),
	    device_get_unit(dev));
	if (error != 0) {
		device_printf(dev, "cannot attach Am79900\n");
		goto fail_dmap;
	}

	error = bus_setup_intr(dev, lesc->sc_ires, INTR_MPSAFE,
	    am79900_intr, sc, &lesc->sc_ih, sc->ifp->if_serializer);
	if (error != 0) {
		device_printf(dev, "cannot set up interrupt\n");
		goto fail_am79900;
	}

	sc->ifp->if_cpuid = rman_get_cpuid(lesc->sc_ires);
	KKASSERT(sc->ifp->if_cpuid >= 0 && sc->ifp->if_cpuid < ncpus);

	return (0);

 fail_am79900:
	am79900_detach(&lesc->sc_am79900);
 fail_dmap:
	bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
 fail_dmem:
	bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
 fail_dtag:
	bus_dma_tag_destroy(lesc->sc_dmat);
 fail_pdtag:
	bus_dma_tag_destroy(lesc->sc_pdmat);
 fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
 fail_rres:
	bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
 fail_mtx:
	return (error);
}
Exemplo n.º 12
0
static int 
vx_pci_attach(device_t dev)
{
    struct vx_softc *sc = device_get_softc(dev);
    struct ifnet *ifp = &sc->arpcom.ac_if;
    int rid;

    rid = PCIR_MAPS;
    sc->vx_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
	RF_ACTIVE);

    if (sc->vx_res == NULL)
	goto bad;

    sc->vx_btag = rman_get_bustag(sc->vx_res);
    sc->vx_bhandle = rman_get_bushandle(sc->vx_res);

    rid = 0;
    sc->vx_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	RF_SHAREABLE | RF_ACTIVE);

    if (sc->vx_irq == NULL)
	goto bad;

    if (vxattach(dev) == 0) {
	goto bad;
    }

    /* defect check for 3C590 */
    if (pci_get_device(dev) == PCI_PRODUCT_3COM_3C590) {
	GO_WINDOW(0);
	if (vxbusyeeprom(sc))
	    goto bad;
	CSR_WRITE_2(sc, VX_W0_EEPROM_COMMAND,
	    EEPROM_CMD_RD | EEPROM_SOFT_INFO_2);
	if (vxbusyeeprom(sc))
	    goto bad;
	if (!(CSR_READ_2(sc, VX_W0_EEPROM_DATA) & NO_RX_OVN_ANOMALY)) {
	    kprintf("Warning! Defective early revision adapter!\n");
	}
    }

    ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->vx_irq));

    if (bus_setup_intr(dev, sc->vx_irq, INTR_MPSAFE,
		       vxintr, sc, &sc->vx_intrhand, 
		       ifp->if_serializer)
    ) {
	ether_ifdetach(&sc->arpcom.ac_if);
	goto bad;
    }

    return(0);

bad:
    if (sc->vx_res != NULL)
	bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->vx_res);
    if (sc->vx_irq != NULL)
	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vx_irq);
    return(ENXIO);
}
Exemplo n.º 13
0
int
sn_attach(device_t dev)
{
	struct sn_softc *sc = device_get_softc(dev);
	struct ifnet   *ifp = &sc->arpcom.ac_if;
	u_short         i;
	u_char         *p;
	int             rev;
	u_short         address;
	int		j;
	int		error;

	sn_activate(dev);

	snstop(sc);

	sc->dev = dev;
	sc->pages_wanted = -1;

	device_printf(dev, " ");

	SMC_SELECT_BANK(3);
	rev = inw(BASE + REVISION_REG_W);
	if (chip_ids[(rev >> 4) & 0xF])
		kprintf("%s ", chip_ids[(rev >> 4) & 0xF]);

	SMC_SELECT_BANK(1);
	i = inw(BASE + CONFIG_REG_W);
	kprintf("%s\n", i & CR_AUI_SELECT ? "AUI" : "UTP");

	if (sc->pccard_enaddr)
		for (j = 0; j < 3; j++) {
			u_short	w;

			w = (u_short)sc->arpcom.ac_enaddr[j * 2] | 
				(((u_short)sc->arpcom.ac_enaddr[j * 2 + 1]) << 8);
			outw(BASE + IAR_ADDR0_REG_W + j * 2, w);
		}

	/*
	 * Read the station address from the chip. The MAC address is bank 1,
	 * regs 4 - 9
	 */
	SMC_SELECT_BANK(1);
	p = (u_char *) & sc->arpcom.ac_enaddr;
	for (i = 0; i < 6; i += 2) {
		address = inw(BASE + IAR_ADDR0_REG_W + i);
		p[i + 1] = address >> 8;
		p[i] = address & 0xFF;
	}
	ifp->if_softc = sc;
	if_initname(ifp, "sn", device_get_unit(dev));
	ifp->if_mtu = ETHERMTU;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_start = snstart;
	ifp->if_ioctl = snioctl;
	ifp->if_watchdog = snwatchdog;
	ifp->if_init = sninit;
	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
	ifq_set_ready(&ifp->if_snd);
	ifp->if_timer = 0;

	ether_ifattach(ifp, sc->arpcom.ac_enaddr, NULL);

	ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->irq_res));

	error = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE,
			       sn_intr, sc, &sc->intrhand,
			       ifp->if_serializer);
	if (error) {
		ether_ifdetach(ifp);
		sn_deactivate(dev);
		return error;
	}

	return 0;
}