Esempio n. 1
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 < sizeof(le_isa_params) /
		    sizeof(le_isa_params[0]); 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;
	}

	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;
	}

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

	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);
}
Esempio n. 2
0
static int
ath_ahb_attach(device_t dev)
{
    struct ath_ahb_softc *psc = device_get_softc(dev);
    struct ath_softc *sc = &psc->sc_sc;
    int error = ENXIO;
    int rid;
    long eepromaddr;
    uint8_t *p;

    sc->sc_dev = dev;

    rid = 0;
    psc->sc_sr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
    if (psc->sc_sr == NULL) {
        device_printf(dev, "cannot map register space\n");
        goto bad;
    }

    if (resource_long_value(device_get_name(dev), device_get_unit(dev),
                            "eepromaddr", &eepromaddr) != 0) {
        device_printf(dev, "cannot fetch 'eepromaddr' from hints\n");
        goto bad0;
    }
    rid = 0;
    device_printf(sc->sc_dev, "eeprom @ %p\n", (void *) eepromaddr);
    psc->sc_eeprom = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, (uintptr_t) eepromaddr,
                                        (uintptr_t) eepromaddr + (uintptr_t) ((ATH_EEPROM_DATA_SIZE * 2) - 1), 0, RF_ACTIVE);
    if (psc->sc_eeprom == NULL) {
        device_printf(dev, "cannot map eeprom space\n");
        goto bad0;
    }

    /* XXX uintptr_t is a bandaid for ia64; to be fixed */
    sc->sc_st = (HAL_BUS_TAG)(uintptr_t) rman_get_bustag(psc->sc_sr);
    sc->sc_sh = (HAL_BUS_HANDLE) rman_get_bushandle(psc->sc_sr);
    /*
     * Mark device invalid so any interrupts (shared or otherwise)
     * that arrive before the HAL is setup are discarded.
     */
    sc->sc_invalid = 1;

    /* Copy the EEPROM data out */
    sc->sc_eepromdata = malloc(ATH_EEPROM_DATA_SIZE * 2, M_TEMP, M_NOWAIT | M_ZERO);
    if (sc->sc_eepromdata == NULL) {
        device_printf(dev, "cannot allocate memory for eeprom data\n");
        goto bad1;
    }
    device_printf(sc->sc_dev, "eeprom data @ %p\n", (void *) rman_get_bushandle(psc->sc_eeprom));
    /* XXX why doesn't this work? -adrian */
#if 0
    bus_space_read_multi_1(
        rman_get_bustag(psc->sc_eeprom),
        rman_get_bushandle(psc->sc_eeprom),
        0, (u_int8_t *) sc->sc_eepromdata, ATH_EEPROM_DATA_SIZE * 2);
#endif
    p = (void *) rman_get_bushandle(psc->sc_eeprom);
    memcpy(sc->sc_eepromdata, p, ATH_EEPROM_DATA_SIZE * 2);

    /*
     * Arrange interrupt line.
     */
    rid = 0;
    psc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE|RF_ACTIVE);
    if (psc->sc_irq == NULL) {
        device_printf(dev, "could not map interrupt\n");
        goto bad1;
    }
    if (bus_setup_intr(dev, psc->sc_irq,
                       INTR_TYPE_NET | INTR_MPSAFE,
                       NULL, ath_intr, sc, &psc->sc_ih)) {
        device_printf(dev, "could not establish interrupt\n");
        goto bad2;
    }

    /*
     * Setup DMA descriptor area.
     */
    if (bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
                           1, 0,			/* alignment, bounds */
                           BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
                           BUS_SPACE_MAXADDR,	/* highaddr */
                           NULL, NULL,		/* filter, filterarg */
                           0x3ffff,			/* maxsize XXX */
                           ATH_MAX_SCATTER,		/* nsegments */
                           0x3ffff,			/* maxsegsize XXX */
                           BUS_DMA_ALLOCNOW,	/* flags */
                           NULL,			/* lockfunc */
                           NULL,			/* lockarg */
                           &sc->sc_dmat)) {
        device_printf(dev, "cannot allocate DMA tag\n");
        goto bad3;
    }

    ATH_LOCK_INIT(sc);

    error = ath_attach(AR9130_DEVID, sc);
    if (error == 0)					/* success */
        return 0;

    ATH_LOCK_DESTROY(sc);
    bus_dma_tag_destroy(sc->sc_dmat);
bad3:
    bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih);
bad2:
    bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq);
bad1:
    bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_eeprom);
bad0:
    bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr);
bad:
    /* XXX?! */
    if (sc->sc_eepromdata)
        free(sc->sc_eepromdata, M_TEMP);
    return (error);
}
Esempio n. 3
0
/*---------------------------------------------------------------------------*
 *	attach
 *---------------------------------------------------------------------------*/
static int
iavc_isa_attach(device_t dev)
{
	struct iavc_softc *sc;
	void *ih = 0;
	int unit = device_get_unit(dev);
	int irq;
	int error;
	
	sc = iavc_find_sc(unit);	/* get softc */	
	
	sc->sc_resources.irq_rid = 0;
	
	if(!(sc->sc_resources.irq =
		bus_alloc_resource(dev, SYS_RES_IRQ,
			&sc->sc_resources.irq_rid,
			0UL, ~0UL, 1, RF_ACTIVE)))
	{
		kprintf("iavc%d: can't allocate irq\n",unit);
		bus_release_resource(dev, SYS_RES_IOPORT,
				sc->sc_resources.io_rid[0],
	                        sc->sc_resources.io_base[0]);
		return(ENXIO);
	}

	irq = rman_get_start(sc->sc_resources.irq);

	if(b1_irq_table[irq] == 0)
	{
		kprintf("iavc%d: ERROR, illegal irq %d configured!\n",unit, irq);
		bus_release_resource(dev, SYS_RES_IOPORT,
				sc->sc_resources.io_rid[0],
	                        sc->sc_resources.io_base[0]);
		bus_release_resource(dev, SYS_RES_IRQ,
				sc->sc_resources.irq_rid,
				sc->sc_resources.irq);
		return(ENXIO);
	}
	
	memset(&sc->sc_txq, 0, sizeof(struct ifqueue));
	sc->sc_txq.ifq_maxlen = sc->sc_capi.sc_nbch * 4;

	sc->sc_intr = FALSE;
	sc->sc_state = IAVC_DOWN;
	sc->sc_blocked = FALSE;

	/* setup capi link */
	
	sc->sc_capi.load = iavc_load;
	sc->sc_capi.reg_appl = iavc_register;
	sc->sc_capi.rel_appl = iavc_release;
	sc->sc_capi.send = iavc_send;
	sc->sc_capi.ctx = (void*) sc;

	if (capi_ll_attach(&sc->sc_capi))
	{
		kprintf("iavc%d: capi attach failed\n", unit);
		return(ENXIO);
	}

	/* setup the interrupt */

	error = bus_setup_intr(dev, sc->sc_resources.irq, 0,
			      (void(*)(void*))iavc_isa_intr,
			      sc, &ih, NULL);
	if (error) {
		kprintf("iavc%d: irq setup failed\n", unit);
		bus_release_resource(dev, SYS_RES_IOPORT,
				sc->sc_resources.io_rid[0],
	                        sc->sc_resources.io_base[0]);
		bus_release_resource(dev, SYS_RES_IRQ,
				sc->sc_resources.irq_rid,
				sc->sc_resources.irq);
		return(ENXIO);
	}

	/* the board is now ready to be loaded */

	return(0);
}
Esempio n. 4
0
static int
obio_attach(device_t dev)
{
	struct obio_softc *sc = device_get_softc(dev);
	int rid;

	sc->oba_mem_rman.rm_type = RMAN_ARRAY;
	sc->oba_mem_rman.rm_descr = "OBIO memory";
	if (rman_init(&sc->oba_mem_rman) != 0 ||
	    rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START,
	        OBIO_MEM_END) != 0)
		panic("obio_attach: failed to set up I/O rman");

	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
	sc->oba_irq_rman.rm_descr = "OBIO IRQ";
	if (rman_init(&sc->oba_irq_rman) != 0 ||
	    rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0)
		panic("obio_attach: failed to set up IRQ rman");

	/* Hook up our interrupt handler. */
	if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
	    RT305X_INTR, RT305X_INTR, 1,
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, obio_intr, NULL,
	    sc, &sc->sc_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}

	/* Hook up our FAST interrupt handler. */
	if ((sc->sc_fast_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
	    RT305X_FAST_INTR, RT305X_FAST_INTR, 1,
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_fast_irq, INTR_TYPE_MISC, obio_intr,
	    NULL, sc, &sc->sc_fast_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}

	/* disable all interrupts */
	rt305x_ic_set(IC_INT_DIS, IC_INT_MASK|IC_LINE_GLOBAL);

	bus_generic_probe(dev);

	obio_add_res_child(dev, "rt305x_sysctl", 0, 
	    SYSCTL_BASE, (SYSCTL_END - SYSCTL_BASE + 1),
	    IC_SYSCTL);
	obio_add_res_child(dev, "rt305x_ic", 0, 
	    INTCTL_BASE, (INTCTL_END - INTCTL_BASE + 1),
	    -1);
#ifdef notyet
	obio_add_res_child(dev, "timer",0, 
	    TIMER_BASE, (TIMER_END - TIMER_BASE  + 1),
	    IC_TIMER0);
	obio_add_res_child(dev, "rt305x_memc", 0,
	    MEMCTRL_BASE, (MEMCTRL_END - MEMCTRL_BASE + 1),
	    -1);
	obio_add_res_child(dev, "pcm", 	0, 
	    PCM_BASE, (PCM_END - PCM_BASE  + 1),
	    IC_PCM);
#endif
	obio_add_res_child(dev, "uart", 0, 
	    UART_BASE, (UART_END - UART_BASE + 1),
	    IC_UART);
	obio_add_res_child(dev, "gpio", 0, 
	    PIO_BASE, (PIO_END - PIO_BASE  + 1),
	    IC_PIO);
#ifdef notyet
	obio_add_res_child(dev, "rt305x_dma", 0,
	    GDMA_BASE, (GDMA_END - GDMA_BASE + 1),
	    IC_DMA);
	obio_add_res_child(dev, "rt305x_nandc", 0,
	    NANDFC_BASE, (NANDFC_END - NANDFC_BASE  + 1),
	    IC_NAND);
	obio_add_res_child(dev, "i2c", 	0,
	    I2C_BASE, (I2C_END - I2C_BASE  + 1),
	    -1);
	obio_add_res_child(dev, "i2s", 0,
	    I2S_BASE, (I2S_END - I2S_BASE  + 1),
	    IC_I2S);
#endif
	obio_add_res_child(dev, "spi", 0, 
	    SPI_BASE, (SPI_END - SPI_BASE  + 1),
	    -1);
	obio_add_res_child(dev, "uart", 1,
	    UARTLITE_BASE, (UARTLITE_END - UARTLITE_BASE + 1),
	    IC_UARTLITE);
#if !defined(RT5350) && !defined(MT7620)
	obio_add_res_child(dev, "cfi", 	0,
	    FLASH_BASE, (FLASH_END - FLASH_BASE  + 1),
	    -1);
	obio_add_res_child(dev, "dwcotg", 0,
	    USB_OTG_BASE, (USB_OTG_END - USB_OTG_BASE  + 1),
	    IC_OTG);
#else
	obio_add_res_child(dev, "ehci", 0,
	    USB_OTG_BASE, (USB_OTG_END - USB_OTG_BASE  + 1),
	    IC_OTG);
	obio_add_res_child(dev, "ohci", 0,
	    USB_OHCI_BASE, (USB_OHCI_END - USB_OHCI_BASE + 1),
	    IC_OTG);
#endif
	obio_add_res_child(dev, "switch", 0,
	    ETHSW_BASE, (ETHSW_END - ETHSW_BASE  + 1),
	    IC_ETHSW);

	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);

	/* enable IC */
	rt305x_ic_set(IC_INT_ENA, IC_LINE_GLOBAL);

	return (0);
}
Esempio n. 5
0
static int
atse_attach_nexus(device_t dev)
{
	struct atse_softc *sc;
	int error;

	sc = device_get_softc(dev);
	sc->atse_dev = dev;
	sc->atse_unit = device_get_unit(dev);

	/* Get RX and TX IRQ and FIFO information from hints. */
	error = atse_resource_int(dev, "rx_irq", &sc->atse_rx_irq);
	error += atse_resource_long(dev, "rx_maddr", &sc->atse_rx_maddr);
	error += atse_resource_long(dev, "rx_msize", &sc->atse_rx_msize);
	error += atse_resource_long(dev, "rxc_maddr", &sc->atse_rxc_maddr);
	error += atse_resource_long(dev, "rxc_msize", &sc->atse_rxc_msize);
	error += atse_resource_int(dev, "tx_irq", &sc->atse_tx_irq);
	error += atse_resource_long(dev, "tx_maddr", &sc->atse_tx_maddr);
	error += atse_resource_long(dev, "tx_msize", &sc->atse_tx_msize);
	error += atse_resource_long(dev, "txc_maddr", &sc->atse_txc_maddr);
	error += atse_resource_long(dev, "txc_msize", &sc->atse_txc_msize);
	if (error != 0)
		return (error);

	/* Avalon-MM, atse management register region. */
	sc->atse_mem_rid = 0;
	sc->atse_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &sc->atse_mem_rid, RF_ACTIVE);
	if (sc->atse_mem_res == NULL) {
		device_printf(dev, "failed to map memory for ctrl region\n");
		return (ENXIO);
	}

	/*
	 * (Optional) RX IRQ and memory mapped regions.
	 * 0x00: 2 * 32bit FIFO data,
	 * 0x20: 8 * 32bit FIFO ctrl, Avalon-ST Sink to Avalon-MM R-Slave.
	 */
	sc->atse_rx_irq_rid = 0;
	sc->atse_rx_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
	    &sc->atse_rx_irq_rid, sc->atse_rx_irq, sc->atse_rx_irq, 1,
	    RF_ACTIVE | RF_SHAREABLE);

	sc->atse_rx_mem_rid = 0;
	sc->atse_rx_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &sc->atse_rx_mem_rid, sc->atse_rx_maddr, sc->atse_rx_maddr +
	    sc->atse_rx_msize, sc->atse_rx_msize, RF_ACTIVE);
	if (sc->atse_rx_mem_res == NULL) {
		device_printf(dev, "failed to map memory for RX\n");
		goto err;
        }
	sc->atse_rxc_mem_rid = 0;
	sc->atse_rxc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &sc->atse_rxc_mem_rid, sc->atse_rxc_maddr, sc->atse_rxc_maddr +
	    sc->atse_rxc_msize, sc->atse_rxc_msize, RF_ACTIVE);
	if (sc->atse_rxc_mem_res == NULL) {
		device_printf(dev, "failed to map memory for RX control\n");
		goto err;
        }

	/*
	 * (Optional) TX IRQ and memory mapped regions.
	 * 0x00: 2 * 32bit FIFO data,
	 * 0x20: 8 * 32bit FIFO ctrl, Avalon-MM W-Slave to Avalon-ST Source.
	 */
	sc->atse_tx_irq_rid = 0;
	sc->atse_tx_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
	    &sc->atse_tx_irq_rid, sc->atse_tx_irq, sc->atse_tx_irq, 1,
	    RF_ACTIVE | RF_SHAREABLE);

	sc->atse_tx_mem_rid = 0;
	sc->atse_tx_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &sc->atse_tx_mem_rid, sc->atse_tx_maddr, sc->atse_tx_maddr +
	    sc->atse_tx_msize, sc->atse_tx_msize, RF_ACTIVE);
	if (sc->atse_tx_mem_res == NULL) {
		device_printf(dev, "failed to map memory for TX\n");
		goto err;
	}
	sc->atse_txc_mem_rid = 0;
	sc->atse_txc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &sc->atse_txc_mem_rid, sc->atse_txc_maddr, sc->atse_txc_maddr +
	    sc->atse_txc_msize, sc->atse_txc_msize, RF_ACTIVE);
	if (sc->atse_txc_mem_res == NULL) {
		device_printf(dev, "failed to map memory for TX control\n");
		goto err;
	}

	error = atse_attach(dev);
	if (error)
		goto err;

	return (0);

err:
	/* Cleanup. */
	atse_detach_resources(dev);

	return (error);
}
Esempio n. 6
0
static int
tws_attach(device_t dev)
{
    struct tws_softc *sc = device_get_softc(dev);
    u_int32_t bar;
    int error=0,i;

    /* no tracing yet */
    /* Look up our softc and initialize its fields. */
    sc->tws_dev = dev;
    sc->device_id = pci_get_device(dev);
    sc->subvendor_id = pci_get_subvendor(dev);
    sc->subdevice_id = pci_get_subdevice(dev);

    /* Intialize mutexes */
    mtx_init( &sc->q_lock, "tws_q_lock", NULL, MTX_DEF);
    mtx_init( &sc->sim_lock,  "tws_sim_lock", NULL, MTX_DEF);
    mtx_init( &sc->gen_lock,  "tws_gen_lock", NULL, MTX_DEF);
    mtx_init( &sc->io_lock,  "tws_io_lock", NULL, MTX_DEF | MTX_RECURSE);
    callout_init(&sc->stats_timer, CALLOUT_MPSAFE);

    if ( tws_init_trace_q(sc) == FAILURE )
        printf("trace init failure\n");
    /* send init event */
    mtx_lock(&sc->gen_lock);
    tws_send_event(sc, TWS_INIT_START);
    mtx_unlock(&sc->gen_lock);


#if _BYTE_ORDER == _BIG_ENDIAN
    TWS_TRACE(sc, "BIG endian", 0, 0);
#endif
    /* sysctl context setup */
    sysctl_ctx_init(&sc->tws_clist);
    sc->tws_oidp = SYSCTL_ADD_NODE(&sc->tws_clist,
                                   SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
                                   device_get_nameunit(dev), 
                                   CTLFLAG_RD, 0, "");
    if ( sc->tws_oidp == NULL ) {
        tws_log(sc, SYSCTL_TREE_NODE_ADD);
        goto attach_fail_1;
    }
    SYSCTL_ADD_STRING(&sc->tws_clist, SYSCTL_CHILDREN(sc->tws_oidp),
                      OID_AUTO, "driver_version", CTLFLAG_RD,
                      TWS_DRIVER_VERSION_STRING, 0, "TWS driver version");

    pci_enable_busmaster(dev);

    bar = pci_read_config(dev, TWS_PCI_BAR0, 4);
    TWS_TRACE_DEBUG(sc, "bar0 ", bar, 0);
    bar = pci_read_config(dev, TWS_PCI_BAR1, 4);
    bar = bar & ~TWS_BIT2;
    TWS_TRACE_DEBUG(sc, "bar1 ", bar, 0);
 
    /* MFA base address is BAR2 register used for 
     * push mode. Firmware will evatualy move to 
     * pull mode during witch this needs to change
     */ 
#ifndef TWS_PULL_MODE_ENABLE
    sc->mfa_base = (u_int64_t)pci_read_config(dev, TWS_PCI_BAR2, 4);
    sc->mfa_base = sc->mfa_base & ~TWS_BIT2;
    TWS_TRACE_DEBUG(sc, "bar2 ", sc->mfa_base, 0);
#endif

    /* allocate MMIO register space */ 
    sc->reg_res_id = TWS_PCI_BAR1; /* BAR1 offset */
    if ((sc->reg_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
                                &(sc->reg_res_id), 0, ~0, 1, RF_ACTIVE))
                                == NULL) {
        tws_log(sc, ALLOC_MEMORY_RES);
        goto attach_fail_1;
    }
    sc->bus_tag = rman_get_bustag(sc->reg_res);
    sc->bus_handle = rman_get_bushandle(sc->reg_res);

#ifndef TWS_PULL_MODE_ENABLE
    /* Allocate bus space for inbound mfa */ 
    sc->mfa_res_id = TWS_PCI_BAR2; /* BAR2 offset */
    if ((sc->mfa_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
                          &(sc->mfa_res_id), 0, ~0, 0x100000, RF_ACTIVE))
                                == NULL) {
        tws_log(sc, ALLOC_MEMORY_RES);
        goto attach_fail_2;
    }
    sc->bus_mfa_tag = rman_get_bustag(sc->mfa_res);
    sc->bus_mfa_handle = rman_get_bushandle(sc->mfa_res);
#endif

    /* Allocate and register our interrupt. */
    sc->intr_type = TWS_INTx; /* default */

    if ( tws_enable_msi )
        sc->intr_type = TWS_MSI;
    if ( tws_setup_irq(sc) == FAILURE ) {
        tws_log(sc, ALLOC_MEMORY_RES);
        goto attach_fail_3;
    }

    /*
     * Create a /dev entry for this device.  The kernel will assign us
     * a major number automatically.  We use the unit number of this
     * device as the minor number and name the character device
     * "tws<unit>".
     */
    sc->tws_cdev = make_dev(&tws_cdevsw, device_get_unit(dev),
        UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "tws%u", 
        device_get_unit(dev));
    sc->tws_cdev->si_drv1 = sc;

    if ( tws_init(sc) == FAILURE ) {
        tws_log(sc, TWS_INIT_FAILURE);
        goto attach_fail_4;
    }
    if ( tws_init_ctlr(sc) == FAILURE ) {
        tws_log(sc, TWS_CTLR_INIT_FAILURE);
        goto attach_fail_4;
    }
    if ((error = tws_cam_attach(sc))) {
        tws_log(sc, TWS_CAM_ATTACH);
        goto attach_fail_4;
    }
    /* send init complete event */
    mtx_lock(&sc->gen_lock);
    tws_send_event(sc, TWS_INIT_COMPLETE);
    mtx_unlock(&sc->gen_lock);
        
    TWS_TRACE_DEBUG(sc, "attached successfully", 0, sc->device_id);
    return(0);

attach_fail_4:
    tws_teardown_intr(sc);
    destroy_dev(sc->tws_cdev);
    if (sc->dma_mem_phys)
	    bus_dmamap_unload(sc->cmd_tag, sc->cmd_map);
    if (sc->dma_mem)
	    bus_dmamem_free(sc->cmd_tag, sc->dma_mem, sc->cmd_map);
    if (sc->cmd_tag)
	    bus_dma_tag_destroy(sc->cmd_tag);
attach_fail_3:
    for(i=0;i<sc->irqs;i++) {
        if ( sc->irq_res[i] ){
            if (bus_release_resource(sc->tws_dev,
                 SYS_RES_IRQ, sc->irq_res_id[i], sc->irq_res[i]))
                TWS_TRACE(sc, "bus irq res", 0, 0);
        }
    }
#ifndef TWS_PULL_MODE_ENABLE
attach_fail_2: 
#endif
    if ( sc->mfa_res ){
        if (bus_release_resource(sc->tws_dev,
                 SYS_RES_MEMORY, sc->mfa_res_id, sc->mfa_res))
            TWS_TRACE(sc, "bus release ", 0, sc->mfa_res_id);
    }
    if ( sc->reg_res ){
        if (bus_release_resource(sc->tws_dev,
                 SYS_RES_MEMORY, sc->reg_res_id, sc->reg_res))
            TWS_TRACE(sc, "bus release2 ", 0, sc->reg_res_id);
    }
attach_fail_1:
    mtx_destroy(&sc->q_lock);
    mtx_destroy(&sc->sim_lock);
    mtx_destroy(&sc->gen_lock);
    mtx_destroy(&sc->io_lock);
    sysctl_ctx_free(&sc->tws_clist);
    return (ENXIO);
}
Esempio n. 7
0
/*
 * Non-destructive identify.
 */
static void
ex_isa_identify(driver_t *driver, device_t parent)
{
	device_t	child;
	bus_addr_t	ioport;
	u_char 		enaddr[6];
	u_int		irq;
	int		tmp;
	const char *	desc;
	struct ex_softc sc;
	int		rid;

	if (bootverbose)
		printf("ex_isa_identify()\n");

	for (ioport = 0x200; ioport < 0x3a0; ioport += 0x10) {
		rid = 0;
		sc.ioport = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid,
		    ioport, ioport, 0x10, RF_ACTIVE);
		if (sc.ioport == NULL)
			continue;

		/* No board found at address */
		if (!ex_look_for_card(&sc)) {
			bus_release_resource(parent, SYS_RES_IOPORT, rid,
			    sc.ioport);
			continue;
		}

		if (bootverbose)
			printf("ex: Found card at 0x%03lx!\n", (unsigned long)ioport);

		/* Board in PnP mode */
		if (ex_eeprom_read(&sc, EE_W0) & EE_W0_PNP) {
			/* Reset the card. */
			CSR_WRITE_1(&sc, CMD_REG, Reset_CMD);
			DELAY(500);
			if (bootverbose)
				printf("ex: card at 0x%03lx in PnP mode!\n", (unsigned long)ioport);
			bus_release_resource(parent, SYS_RES_IOPORT, rid,
			    sc.ioport);
			continue;
		}

		bzero(enaddr, sizeof(enaddr));

		/* Reset the card. */
		CSR_WRITE_1(&sc, CMD_REG, Reset_CMD);
		DELAY(400);

		ex_get_address(&sc, enaddr);
		tmp = ex_eeprom_read(&sc, EE_W1) & EE_W1_INT_SEL;

		/* work out which set of irq <-> internal tables to use */
		if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) {
			irq  = plus_ee2irqmap[tmp];
			desc = "Intel Pro/10+";
		} else {
			irq = ee2irqmap[tmp];
			desc = "Intel Pro/10";
		}

		bus_release_resource(parent, SYS_RES_IOPORT, rid, sc.ioport);
		child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ex", -1);
		device_set_desc_copy(child, desc);
		device_set_driver(child, driver);
		bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
		bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, EX_IOSIZE);
		if (bootverbose)
			printf("ex: Adding board at 0x%03lx, irq %d\n",
			   (unsigned long)ioport, irq);
	}

	return;
}
Esempio n. 8
0
static struct resource *
lbc_alloc_resource(device_t bus, device_t child, int type, int *rid,
    rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
	struct lbc_softc *sc;
	struct lbc_devinfo *di;
	struct resource_list_entry *rle;
	struct resource *res;
	struct rman *rm;
	int needactivate;

	/* We only support default allocations. */
	if (!RMAN_IS_DEFAULT_RANGE(start, end))
		return (NULL);

	sc = device_get_softc(bus);
	if (type == SYS_RES_IRQ)
		return (bus_alloc_resource(bus, type, rid, start, end, count,
		    flags));

	/*
	 * Request for the default allocation with a given rid: use resource
	 * list stored in the local device info.
	 */
	if ((di = device_get_ivars(child)) == NULL)
		return (NULL);

	if (type == SYS_RES_IOPORT)
		type = SYS_RES_MEMORY;

	rid = &di->di_bank;

	rle = resource_list_find(&di->di_res, type, *rid);
	if (rle == NULL) {
		device_printf(bus, "no default resources for "
		    "rid = %d, type = %d\n", *rid, type);
		return (NULL);
	}
	start = rle->start;
	count = rle->count;
	end = start + count - 1;

	sc = device_get_softc(bus);

	needactivate = flags & RF_ACTIVE;
	flags &= ~RF_ACTIVE;

	rm = &sc->sc_rman;

	res = rman_reserve_resource(rm, start, end, count, flags, child);
	if (res == NULL) {
		device_printf(bus, "failed to reserve resource %#lx - %#lx "
		    "(%#lx)\n", start, end, count);
		return (NULL);
	}

	rman_set_rid(res, *rid);
	rman_set_bustag(res, &bs_be_tag);
	rman_set_bushandle(res, rman_get_start(res));

	if (needactivate)
		if (bus_activate_resource(child, type, *rid, res)) {
			device_printf(child, "resource activation failed\n");
			rman_release_resource(res);
			return (NULL);
		}

	return (res);
}
Esempio n. 9
0
static int
dpt_pci_attach (device_t dev)
{
	dpt_softc_t *	dpt;
	struct resource *io = NULL;
	struct resource *irq = NULL;
	int		rid;
	void *		ih;
	int		error = 0;

	int		iotype = 0;
	u_int32_t	command;

	command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);

#ifdef DPT_ALLOW_MMIO
	if ((command & PCIM_CMD_MEMEN) != 0) {
		rid = DPT_PCI_MEMADDR;
		iotype = SYS_RES_MEMORY;
		io = bus_alloc_resource(dev, iotype, &rid, 0, ~0, 1, RF_ACTIVE);
	}
#endif
	if (io == NULL && (command &  PCIM_CMD_PORTEN) != 0) {
		rid = DPT_PCI_IOADDR;
		iotype = SYS_RES_IOPORT;
		io = bus_alloc_resource(dev, iotype, &rid, 0, ~0, 1, RF_ACTIVE);
	}

	if (io == NULL) {
		device_printf(dev, "can't allocate register resources\n");
		error = ENOMEM;
		goto bad;
	}

	rid = 0;
	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
				 RF_ACTIVE | RF_SHAREABLE);
	if (!irq) {
		device_printf(dev, "No irq?!\n");
		error = ENOMEM;
		goto bad;
	}

	/* Ensure busmastering is enabled */
	command |= PCIM_CMD_BUSMASTEREN;
	pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);

	if (rman_get_start(io) == (ISA_PRIMARY_WD_ADDRESS - 0x10)) {
#ifdef DPT_DEBUG_WARN
		device_printf(dev, "Mapped as an IDE controller.  "
				   "Disabling SCSI setup\n");
#endif
		error = ENXIO;
		goto bad;
	}

	/* Device registers are offset 0x10 into the register window.  FEH */
	dpt = dpt_alloc(dev, rman_get_bustag(io), rman_get_bushandle(io) + 0x10);
	if (dpt == NULL) {
		error = ENXIO;
		goto bad;
	}

	/* Allocate a dmatag representing the capabilities of this attachment */
	/* XXX Should be a child of the PCI bus dma tag */
	if (bus_dma_tag_create(	/* parent    */	NULL,
				/* alignemnt */	1,
				/* boundary  */	0,
				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
				/* highaddr  */	BUS_SPACE_MAXADDR,
				/* filter    */	NULL,
				/* filterarg */	NULL,
				/* maxsize   */	BUS_SPACE_MAXSIZE_32BIT,
				/* nsegments */	BUS_SPACE_UNRESTRICTED,
				/* maxsegsz  */	BUS_SPACE_MAXSIZE_32BIT,
				/* flags     */	0,
				&dpt->parent_dmat) != 0) {
		dpt_free(dpt);
		error = ENXIO;
		goto bad;
	}

	crit_enter();

	if (dpt_init(dpt) != 0) {
		dpt_free(dpt);
		error = ENXIO;
		crit_exit();
		goto bad;
	}

	/* Register with the XPT */
	dpt_attach(dpt);

	crit_exit();

	error = bus_setup_intr(dev, irq, 0, dpt_intr, dpt, 
			       &ih, NULL);
	if (error) {
		device_printf(dev, "Unable to register interrupt handler\n");
		error = ENXIO;
		goto bad;
	}

	return (error);

bad:
	if (io)
		bus_release_resource(dev, iotype, 0, io);
	if (irq)
		bus_release_resource(dev, SYS_RES_IRQ, 0, irq);

	return (error);
}
Esempio n. 10
0
static int
kr_attach(device_t dev)
{
	uint8_t			eaddr[ETHER_ADDR_LEN];
	struct ifnet		*ifp;
	struct kr_softc		*sc;
	int			error = 0, rid;
	int			unit;

	sc = device_get_softc(dev);
	unit = device_get_unit(dev);
	sc->kr_dev = dev;

	mtx_init(&sc->kr_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
	    MTX_DEF);
	callout_init_mtx(&sc->kr_stat_callout, &sc->kr_mtx, 0);
	TASK_INIT(&sc->kr_link_task, 0, kr_link_task, sc);
	pci_enable_busmaster(dev);

	/* Map control/status registers. */
	sc->kr_rid = 0;
	sc->kr_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->kr_rid, 
	    RF_ACTIVE);

	if (sc->kr_res == NULL) {
		device_printf(dev, "couldn't map memory\n");
		error = ENXIO;
		goto fail;
	}

	sc->kr_btag = rman_get_bustag(sc->kr_res);
	sc->kr_bhandle = rman_get_bushandle(sc->kr_res);

	/* Allocate interrupts */
	rid = 0;
	sc->kr_rx_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, KR_RX_IRQ,
	    KR_RX_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);

	if (sc->kr_rx_irq == NULL) {
		device_printf(dev, "couldn't map rx interrupt\n");
		error = ENXIO;
		goto fail;
	}

	rid = 0;
	sc->kr_tx_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, KR_TX_IRQ,
	    KR_TX_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);

	if (sc->kr_tx_irq == NULL) {
		device_printf(dev, "couldn't map tx interrupt\n");
		error = ENXIO;
		goto fail;
	}

	rid = 0;
	sc->kr_rx_und_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 
	    KR_RX_UND_IRQ, KR_RX_UND_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);

	if (sc->kr_rx_und_irq == NULL) {
		device_printf(dev, "couldn't map rx underrun interrupt\n");
		error = ENXIO;
		goto fail;
	}

	rid = 0;
	sc->kr_tx_ovr_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 
	    KR_TX_OVR_IRQ, KR_TX_OVR_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);

	if (sc->kr_tx_ovr_irq == NULL) {
		device_printf(dev, "couldn't map tx overrun interrupt\n");
		error = ENXIO;
		goto fail;
	}

	/* Allocate ifnet structure. */
	ifp = sc->kr_ifp = if_alloc(IFT_ETHER);

	if (ifp == NULL) {
		device_printf(dev, "couldn't allocate ifnet structure\n");
		error = ENOSPC;
		goto fail;
	}
	ifp->if_softc = sc;
	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = kr_ioctl;
	ifp->if_start = kr_start;
	ifp->if_init = kr_init;

	/* XXX: add real size */
	IFQ_SET_MAXLEN(&ifp->if_snd, 9);
	ifp->if_snd.ifq_maxlen = 9;
	IFQ_SET_READY(&ifp->if_snd);

	ifp->if_capenable = ifp->if_capabilities;

	eaddr[0] = 0x00;
	eaddr[1] = 0x0C;
	eaddr[2] = 0x42;
	eaddr[3] = 0x09;
	eaddr[4] = 0x5E;
	eaddr[5] = 0x6B;

	if (kr_dma_alloc(sc) != 0) {
		error = ENXIO;
		goto fail;
	}

	/* TODO: calculate prescale */
	CSR_WRITE_4(sc, KR_ETHMCP, (165000000 / (1250000 + 1)) & ~1);

	CSR_WRITE_4(sc, KR_MIIMCFG, KR_MIIMCFG_R);
	DELAY(1000);
	CSR_WRITE_4(sc, KR_MIIMCFG, 0);

	/* Do MII setup. */
	error = mii_attach(dev, &sc->kr_miibus, ifp, kr_ifmedia_upd,
	    kr_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
	if (error != 0) {
		device_printf(dev, "attaching PHYs failed\n");
		goto fail;
	}

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

	/* Hook interrupt last to avoid having to lock softc */
	error = bus_setup_intr(dev, sc->kr_rx_irq, INTR_TYPE_NET | INTR_MPSAFE,
	    NULL, kr_rx_intr, sc, &sc->kr_rx_intrhand);

	if (error) {
		device_printf(dev, "couldn't set up rx irq\n");
		ether_ifdetach(ifp);
		goto fail;
	}

	error = bus_setup_intr(dev, sc->kr_tx_irq, INTR_TYPE_NET | INTR_MPSAFE,
	    NULL, kr_tx_intr, sc, &sc->kr_tx_intrhand);

	if (error) {
		device_printf(dev, "couldn't set up tx irq\n");
		ether_ifdetach(ifp);
		goto fail;
	}

	error = bus_setup_intr(dev, sc->kr_rx_und_irq, 
	    INTR_TYPE_NET | INTR_MPSAFE, NULL, kr_rx_und_intr, sc, 
	    &sc->kr_rx_und_intrhand);

	if (error) {
		device_printf(dev, "couldn't set up rx underrun irq\n");
		ether_ifdetach(ifp);
		goto fail;
	}

	error = bus_setup_intr(dev, sc->kr_tx_ovr_irq, 
	    INTR_TYPE_NET | INTR_MPSAFE, NULL, kr_tx_ovr_intr, sc, 
	    &sc->kr_tx_ovr_intrhand);

	if (error) {
		device_printf(dev, "couldn't set up tx overrun irq\n");
		ether_ifdetach(ifp);
		goto fail;
	}

fail:
	if (error) 
		kr_detach(dev);

	return (error);
}
Esempio n. 11
0
static int
ata_cbus_attach(device_t dev)
{
    struct ata_cbus_controller *ctlr = device_get_softc(dev);
    device_t child;
    int rid, unit;

    /* allocate resources */
    rid = ATA_IOADDR_RID;
    if (!(ctlr->io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
					ATA_PC98_IOSIZE, RF_ACTIVE)))
       return ENOMEM;

    rid = ATA_PC98_CTLADDR_RID;
    if (!(ctlr->ctlio = 
	  bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
			     rman_get_start(ctlr->io) + ATA_PC98_CTLOFFSET, ~0,
			     ATA_CTLIOSIZE, RF_ACTIVE))) {
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, ctlr->io);
	return ENOMEM;
    }

    rid = ATA_PC98_BANKADDR_RID;
    if (!(ctlr->bankio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
					    ATA_PC98_BANK, ~0,
					    ATA_PC98_BANKIOSIZE, RF_ACTIVE))) {
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, ctlr->io);
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, ctlr->ctlio);
	return ENOMEM;
    }

    rid = ATA_IRQ_RID;
    if (!(ctlr->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
					     RF_ACTIVE | RF_SHAREABLE))) {
	device_printf(dev, "unable to alloc interrupt\n");
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, ctlr->io);
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, ctlr->ctlio);
	bus_release_resource(dev, SYS_RES_IOPORT, 
			     ATA_PC98_BANKADDR_RID, ctlr->bankio);
	return ENXIO;
    }

    if ((bus_setup_intr(dev, ctlr->irq, ATA_INTR_FLAGS,
			NULL, ata_cbus_intr, ctlr, &ctlr->ih))) {
	device_printf(dev, "unable to setup interrupt\n");
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, ctlr->io);
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, ctlr->ctlio);
	bus_release_resource(dev, SYS_RES_IOPORT, 
			     ATA_PC98_BANKADDR_RID, ctlr->bankio);
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IRQ_RID, ctlr->irq);
	return ENXIO;
    }

    mtx_init(&ctlr->bank_mtx, "ATA cbus bank lock", NULL, MTX_DEF);
    ctlr->hardware_bank = -1;
    ctlr->locked_bank = -1;
    ctlr->restart_bank = -1;

    for (unit = 0; unit < 2; unit++) {
	child = device_add_child(dev, "ata", unit);
	if (child == NULL)
	    device_printf(dev, "failed to add ata child device\n");
	else
	    device_set_ivars(child, (void *)(intptr_t)unit);
    }

    bus_generic_attach(dev);
    return (0);
}
Esempio n. 12
0
static int
octusb_octeon_attach(device_t dev)
{
	struct octusb_octeon_softc *sc = device_get_softc(dev);
	int err;
	int rid;
	int nports;
	int i;

	/* setup controller interface softc */

	/* initialise some bus fields */
	sc->sc_dci.sc_bus.parent = dev;
	sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices;
	sc->sc_dci.sc_bus.devices_max = OCTUSB_MAX_DEVICES;
	sc->sc_dci.sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_dci.sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	nports = cvmx_usb_get_num_ports();
	if (nports > OCTUSB_MAX_PORTS)
		panic("octusb: too many USB ports %d", nports);
	for (i = 0; i < nports; i++) {
		rid = 0;
		sc->sc_dci.sc_irq_res[i] =
		    bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
			       OCTEON_IRQ_USB0 + i, OCTEON_IRQ_USB0 + i, 1, RF_ACTIVE);
		if (!(sc->sc_dci.sc_irq_res[i])) {
			goto error;
		}

#if (__FreeBSD_version >= 700031)
		err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res[i], INTR_TYPE_BIO | INTR_MPSAFE,
		    NULL, (driver_intr_t *)octusb_interrupt, sc, &sc->sc_dci.sc_intr_hdl[i]);
#else
		err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res[i], INTR_TYPE_BIO | INTR_MPSAFE,
		    (driver_intr_t *)octusb_interrupt, sc, &sc->sc_dci.sc_intr_hdl[i]);
#endif
		if (err) {
			sc->sc_dci.sc_intr_hdl[i] = NULL;
			goto error;
		}
	}

	sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_dci.sc_bus.bdev)) {
		goto error;
	}
	device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus);


	err = octusb_init(&sc->sc_dci);
	if (!err) {
		err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev);
	}
	if (err) {
		goto error;
	}
	return (0);

error:
	octusb_octeon_detach(dev);
	return (ENXIO);
}
Esempio n. 13
0
File: if_el.c Progetto: MarginC/kame
/* Probe routine.  See if the card is there and at the right place. */
static int
el_probe(device_t dev)
{
	struct el_softc *sc;
	u_short base; /* Just for convenience */
	u_char station_addr[ETHER_ADDR_LEN];
	int i, rid;

	/* Grab some info for our structure */
	sc = device_get_softc(dev);

	if (isa_get_logicalid(dev))		/* skip PnP probes */
		return (ENXIO);

	if ((base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0)
		return (ENXIO);

	/* First check the base */
	if((base < 0x280) || (base > 0x3f0)) {
		device_printf(dev,
		    "ioaddr must be between 0x280 and 0x3f0\n");
		return(ENXIO);
	}

	/* Temporarily map the resources. */
	rid = 0;
	sc->el_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
	    0, ~0, EL_IOSIZ, RF_ACTIVE);

	if (sc->el_res == NULL)
		return(ENXIO);

	sc->el_btag = rman_get_bustag(sc->el_res);
	sc->el_bhandle = rman_get_bushandle(sc->el_res);
	mtx_init(&sc->el_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
	    MTX_DEF | MTX_RECURSE);
	EL_LOCK(sc);

	/* Now attempt to grab the station address from the PROM
	 * and see if it contains the 3com vendor code.
	 */
	dprintf(("Probing 3c501 at 0x%x...\n",base));

	/* Reset the board */
	dprintf(("Resetting board...\n"));
	CSR_WRITE_1(sc,EL_AC,EL_AC_RESET);
	DELAY(5);
	CSR_WRITE_1(sc,EL_AC,0);
	dprintf(("Reading station address...\n"));
	/* Now read the address */
	for(i=0;i<ETHER_ADDR_LEN;i++) {
		CSR_WRITE_1(sc,EL_GPBL,i);
		station_addr[i] = CSR_READ_1(sc,EL_EAW);
	}

	/* Now release resources */
	bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->el_res);
	EL_UNLOCK(sc);
	mtx_destroy(&sc->el_mtx);

	dprintf(("Address is %6D\n",station_addr, ":"));

	/* If the vendor code is ok, return a 1.  We'll assume that
	 * whoever configured this system is right about the IRQ.
	 */
	if((station_addr[0] != 0x02) || (station_addr[1] != 0x60)
	   || (station_addr[2] != 0x8c)) {
		dprintf(("Bad vendor code.\n"));
		return(ENXIO);
	} else {
		dprintf(("Vendor code ok.\n"));
		/* Copy the station address into the arpcom structure */
		bcopy(station_addr,sc->arpcom.ac_enaddr,ETHER_ADDR_LEN);
	}

	device_set_desc(dev, "3Com 3c501 Ethernet");

	return(0);
}
Esempio n. 14
0
static int
rp_pciattach(device_t dev)
{
	int	num_ports, num_aiops;
	int	aiop;
	CONTROLLER_t	*ctlp;
	int	unit;
	int	retval;
	u_int32_t	stcmd;

	ctlp = device_get_softc(dev);
	bzero(ctlp, sizeof(*ctlp));
	ctlp->dev = dev;
	unit = device_get_unit(dev);
	ctlp->aiop2rid = rp_pci_aiop2rid;
	ctlp->aiop2off = rp_pci_aiop2off;
	ctlp->ctlmask = rp_pci_ctlmask;

	/* Wake up the device. */
	stcmd = pci_read_config(dev, PCIR_COMMAND, 4);
	if ((stcmd & PCIM_CMD_PORTEN) == 0) {
		stcmd |= (PCIM_CMD_PORTEN);
		pci_write_config(dev, PCIR_COMMAND, 4, stcmd);
	}

	/* The IO ports of AIOPs for a PCI controller are continuous. */
	ctlp->io_num = 1;
	ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * ctlp->io_num, M_DEVBUF, M_NOWAIT | M_ZERO);
	ctlp->io = malloc(sizeof(*(ctlp->io)) * ctlp->io_num, M_DEVBUF, M_NOWAIT | M_ZERO);
	if (ctlp->io_rid == NULL || ctlp->io == NULL) {
		device_printf(dev, "rp_pciattach: Out of memory.\n");
		retval = ENOMEM;
		goto nogo;
	}

	ctlp->bus_ctlp = NULL;

	ctlp->io_rid[0] = 0x10;
	ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 1, RF_ACTIVE);
	if(ctlp->io[0] == NULL) {
		device_printf(dev, "ioaddr mapping failed for RocketPort(PCI).\n");
		retval = ENXIO;
		goto nogo;
	}

	num_aiops = sPCIInitController(ctlp,
				       MAX_AIOPS_PER_BOARD, 0,
				       FREQ_DIS, 0, (pci_get_devid(dev) >> 16) & 0xffff);

	num_ports = 0;
	for(aiop=0; aiop < num_aiops; aiop++) {
		sResetAiopByNum(ctlp, aiop);
		num_ports += sGetAiopNumChan(ctlp, aiop);
	}

	retval = rp_attachcommon(ctlp, num_aiops, num_ports);
	if (retval != 0)
		goto nogo;

	return (0);

nogo:
	rp_pcireleaseresource(ctlp);

	return (retval);
}
Esempio n. 15
0
/*
 * Attach all the sub-devices we can find
 */
static int
aha_isa_attach(device_t dev)
{
	struct	aha_softc *aha = device_get_softc(dev);
	bus_dma_filter_t *filter;
	void		 *filter_arg;
	bus_addr_t	 lowaddr;
	void		 *ih;
	int		 error = ENOMEM;
	int		 aha_free_needed = 0;

	aha->dev = dev;
	aha->portrid = 0;
	aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &aha->portrid,
	    0, ~0, AHA_NREGS, RF_ACTIVE);
	if (!aha->port) {
		device_printf(dev, "Unable to allocate I/O ports\n");
		goto fail;
	}

	aha->irqrid = 0;
	aha->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &aha->irqrid,
	    RF_ACTIVE);
	if (!aha->irq) {
		device_printf(dev, "Unable to allocate excluse use of irq\n");
		goto fail;
	}

	aha->drqrid = 0;
	aha->drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &aha->drqrid,
	    RF_ACTIVE);
	if (!aha->drq) {
		device_printf(dev, "Unable to allocate drq\n");
		goto fail;
	}

#if 0				/* is the drq ever unset? */
	if (dev->id_drq != -1)
		isa_dmacascade(dev->id_drq);
#endif
	isa_dmacascade(rman_get_start(aha->drq));

	/* Allocate our parent dmatag */
	filter = NULL;
	filter_arg = NULL;
	lowaddr = BUS_SPACE_MAXADDR_24BIT;

	if (bus_dma_tag_create(	/* parent	*/ bus_get_dma_tag(dev),
				/* alignemnt	*/ 1,
				/* boundary	*/ 0,
				/* lowaddr	*/ lowaddr,
				/* highaddr	*/ BUS_SPACE_MAXADDR,
				/* filter	*/ filter,
				/* filterarg	*/ filter_arg,
				/* maxsize	*/ BUS_SPACE_MAXSIZE_24BIT,
				/* nsegments	*/ ~0,
				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_24BIT,
				/* flags	*/ 0,
				/* lockfunc	*/ busdma_lock_mutex,
				/* lockarg	*/ &Giant,
				&aha->parent_dmat) != 0) {
		device_printf(dev, "dma tag create failed.\n");
		goto fail;
        }                              

	if (aha_init(aha)) {
		device_printf(dev, "init failed\n");
		goto fail;
        }
	/*
	 * The 1542A and B look the same.  So we guess based on
	 * the firmware revision.  It appears that only rev 0 is on
	 * the A cards.
	 */
	if (aha->boardid <= BOARD_1542 && aha->fw_major == 0) {
		device_printf(dev, "154xA may not work\n");
		aha->ccb_sg_opcode = INITIATOR_SG_CCB;
		aha->ccb_ccb_opcode = INITIATOR_CCB;
	}
	aha_free_needed++;
	
	error = aha_attach(aha);
	if (error) {
		device_printf(dev, "attach failed\n");
		goto fail;
	}

	error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY,
	    NULL, aha_intr, aha, &ih);
	if (error) {
		device_printf(dev, "Unable to register interrupt handler\n");
                goto fail;
	}

	return (0);
fail: ;
	bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
	bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
	bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
	if (aha_free_needed)
		aha_free(aha);
	return (error);
}
Esempio n. 16
0
static int
dpt_eisa_attach (device_t dev)
{
	dpt_softc_t * dpt;
	struct resource *io = 0;
	struct resource *irq = 0;
	int		s;
	int		rid;
	void *		ih;
	int		error = 0;

	rid = 0;
	io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
	if (!io) {
		device_printf(dev, "No I/O space?!\n");
		error = ENOMEM;
		goto bad;
	}

	rid = 0;
	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE);
	if (!irq) {
		device_printf(dev, "No irq?!\n");
		error = ENOMEM;
		goto bad;
	}

	dpt = dpt_alloc(dev, rman_get_bustag(io),
			rman_get_bushandle(io) + DPT_EISA_EATA_REG_OFFSET);
	if (dpt == NULL) {
		error = ENOMEM;
		goto bad;
	}

	/* Allocate a dmatag representing the capabilities of this attachment */
	/* XXX Should be a child of the EISA bus dma tag */
	if (bus_dma_tag_create(	/* parent    */	NULL,
				/* alignemnt */	1,
				/* boundary  */	0,
				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
				/* highaddr  */	BUS_SPACE_MAXADDR,
				/* filter    */	NULL,
				/* filterarg */	NULL,
				/* maxsize   */	BUS_SPACE_MAXSIZE_32BIT,
				/* nsegments */	~0,
				/* maxsegsz  */	BUS_SPACE_MAXSIZE_32BIT,
				/* flags     */0,
				&dpt->parent_dmat) != 0) {
		dpt_free(dpt);
		error = ENXIO;
		goto bad;
	}

	s = splcam();

	if (dpt_init(dpt) != 0) {
		dpt_free(dpt);
		error = ENXIO;
		goto bad;
	}

	/* Register with the XPT */
	dpt_attach(dpt);

	splx(s);

	if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_ENTROPY, dpt_intr,
			   dpt, &ih)) {
		device_printf(dev, "Unable to register interrupt handler\n");
		error = ENXIO;
		goto bad;
	}

	return (error);

 bad:
	if (io)
		bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
	if (irq)
		bus_release_resource(dev, SYS_RES_IRQ, 0, irq);

	return (error);
}
Esempio n. 17
0
int
scc_bfe_attach(device_t dev, u_int ipc)
{
	struct resource_list_entry *rle;
	struct scc_chan *ch;
	struct scc_class *cl;
	struct scc_mode *m;
	struct scc_softc *sc, *sc0;
	const char *sep;
	bus_space_handle_t bh;
	u_long base, size, start, sz;
	int c, error, mode, sysdev;

	/*
	 * The sc_class field defines the type of SCC we're going to work
	 * with and thus the size of the softc. Replace the generic softc
	 * with one that matches the SCC now that we're certain we handle
	 * the device.
	 */
	sc0 = device_get_softc(dev);
	cl = sc0->sc_class;
	if (cl->size > sizeof(*sc)) {
		sc = malloc(cl->size, M_SCC, M_WAITOK|M_ZERO);
		bcopy(sc0, sc, sizeof(*sc));
		device_set_softc(dev, sc);
	} else
		sc = sc0;

	size = abs(cl->cl_range) << sc->sc_bas.regshft;

	mtx_init(&sc->sc_hwmtx, "scc_hwmtx", NULL, MTX_SPIN);

	/*
	 * Re-allocate. We expect that the softc contains the information
	 * collected by scc_bfe_probe() intact.
	 */
	sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
	    0, ~0, cl->cl_channels * size, RF_ACTIVE);
	if (sc->sc_rres == NULL)
		return (ENXIO);
	sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
	sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);

	/*
	 * Allocate interrupt resources. There may be a different interrupt
	 * per channel. We allocate them all...
	 */
	sc->sc_chan = malloc(sizeof(struct scc_chan) * cl->cl_channels,
	    M_SCC, M_WAITOK | M_ZERO);
	for (c = 0; c < cl->cl_channels; c++) {
		ch = &sc->sc_chan[c];
		/*
		 * XXX temporary hack. If we have more than 1 interrupt
		 * per channel, allocate the first for the channel. At
		 * this time only the macio bus front-end has more than
		 * 1 interrupt per channel and we don't use the 2nd and
		 * 3rd, because we don't support DMA yet.
		 */
		ch->ch_irid = c * ipc;
		ch->ch_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
		    &ch->ch_irid, RF_ACTIVE | RF_SHAREABLE);
		if (ipc == 0)
			break;
	}

	/*
	 * Create the control structures for our children. Probe devices
	 * and query them to see if we can reset the hardware.
	 */
	sysdev = 0;
	base = rman_get_start(sc->sc_rres);
	sz = (size != 0) ? size : rman_get_size(sc->sc_rres);
	start = base + ((cl->cl_range < 0) ? size * (cl->cl_channels - 1) : 0);
	for (c = 0; c < cl->cl_channels; c++) {
		ch = &sc->sc_chan[c];
		resource_list_init(&ch->ch_rlist);
		ch->ch_nr = c + 1;

		if (!SCC_ENABLED(sc, ch))
			goto next;

		ch->ch_enabled = 1;
		resource_list_add(&ch->ch_rlist, sc->sc_rtype, 0, start,
		    start + sz - 1, sz);
		rle = resource_list_find(&ch->ch_rlist, sc->sc_rtype, 0);
		rle->res = &ch->ch_rres;
		bus_space_subregion(rman_get_bustag(sc->sc_rres),
		    rman_get_bushandle(sc->sc_rres), start - base, sz, &bh);
		rman_set_bushandle(rle->res, bh);
		rman_set_bustag(rle->res, rman_get_bustag(sc->sc_rres));

		resource_list_add(&ch->ch_rlist, SYS_RES_IRQ, 0, c, c, 1);
		rle = resource_list_find(&ch->ch_rlist, SYS_RES_IRQ, 0);
		rle->res = (ch->ch_ires != NULL) ? ch->ch_ires :
			    sc->sc_chan[0].ch_ires;

		for (mode = 0; mode < SCC_NMODES; mode++) {
			m = &ch->ch_mode[mode];
			m->m_chan = ch;
			m->m_mode = 1U << mode;
			if ((cl->cl_modes & m->m_mode) == 0 || ch->ch_sysdev)
				continue;
			m->m_dev = device_add_child(dev, NULL, -1);
			device_set_ivars(m->m_dev, (void *)m);
			error = device_probe_child(dev, m->m_dev);
			if (!error) {
				m->m_probed = 1;
				m->m_sysdev = SERDEV_SYSDEV(m->m_dev) ? 1 : 0;
				ch->ch_sysdev |= m->m_sysdev;
			}
		}

	 next:
		start += (cl->cl_range < 0) ? -size : size;
		sysdev |= ch->ch_sysdev;
	}

	/*
	 * Have the hardware driver initialize the hardware. Tell it
	 * whether or not a hardware reset should be performed.
	 */
	if (bootverbose) {
		device_printf(dev, "%sresetting hardware\n",
		    (sysdev) ? "not " : "");
	}
	error = SCC_ATTACH(sc, !sysdev);
	if (error)
		goto fail;

	/*
	 * Setup our interrupt handler. Make it FAST under the assumption
	 * that our children's are fast as well. We make it MPSAFE as soon
	 * as a child sets up a MPSAFE interrupt handler.
	 * Of course, if we can't setup a fast handler, we make it MPSAFE
	 * right away.
	 */
	for (c = 0; c < cl->cl_channels; c++) {
		ch = &sc->sc_chan[c];
		if (ch->ch_ires == NULL)
			continue;
		error = bus_setup_intr(dev, ch->ch_ires,
		    INTR_TYPE_TTY, scc_bfe_intr, NULL, sc,
		    &ch->ch_icookie);
		if (error) {
			error = bus_setup_intr(dev, ch->ch_ires,
			    INTR_TYPE_TTY | INTR_MPSAFE, NULL,
			    (driver_intr_t *)scc_bfe_intr, sc, &ch->ch_icookie);
		} else
			sc->sc_fastintr = 1;

		if (error) {
			device_printf(dev, "could not activate interrupt\n");
			bus_release_resource(dev, SYS_RES_IRQ, ch->ch_irid,
			    ch->ch_ires);
			ch->ch_ires = NULL;
		}
	}
	sc->sc_polled = 1;
	for (c = 0; c < cl->cl_channels; c++) {
		if (sc->sc_chan[0].ch_ires != NULL)
			sc->sc_polled = 0;
	}

	/*
	 * Attach all child devices that were probed successfully.
	 */
	for (c = 0; c < cl->cl_channels; c++) {
		ch = &sc->sc_chan[c];
		for (mode = 0; mode < SCC_NMODES; mode++) {
			m = &ch->ch_mode[mode];
			if (!m->m_probed)
				continue;
			error = device_attach(m->m_dev);
			if (error)
				continue;
			m->m_attached = 1;
		}
	}

	if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) {
		sep = "";
		device_print_prettyname(dev);
		if (sc->sc_fastintr) {
			printf("%sfast interrupt", sep);
			sep = ", ";
		}
		if (sc->sc_polled) {
			printf("%spolled mode", sep);
			sep = ", ";
		}
		printf("\n");
	}

	return (0);

 fail:
	for (c = 0; c < cl->cl_channels; c++) {
		ch = &sc->sc_chan[c];
		if (ch->ch_ires == NULL)
			continue;
		bus_release_resource(dev, SYS_RES_IRQ, ch->ch_irid,
		    ch->ch_ires);
	}
	bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
	return (error);
}
Esempio n. 18
0
static int
hme_sbus_attach(device_t dev)
{
	struct hme_sbus_softc *hsc = device_get_softc(dev);
	struct hme_softc *sc = &hsc->hsc_hme;
	u_int32_t burst;
	u_long start, count;
	int error;

	/*
	 * Map five register banks:
	 *
	 *	bank 0: HME SEB registers
	 *	bank 1: HME ETX registers
	 *	bank 2: HME ERX registers
	 *	bank 3: HME MAC registers
	 *	bank 4: HME MIF registers
	 *
	 */
	sc->sc_sebo = sc->sc_etxo = sc->sc_erxo = sc->sc_maco = sc->sc_mifo = 0;
	hsc->hsc_seb_rid = 0;
	hsc->hsc_seb_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &hsc->hsc_seb_rid, 0, ~0, 1, RF_ACTIVE);
	if (hsc->hsc_seb_res == NULL) {
		device_printf(dev, "cannot map SEB registers\n");
		return (ENXIO);
	}
	sc->sc_sebt = rman_get_bustag(hsc->hsc_seb_res);
	sc->sc_sebh = rman_get_bushandle(hsc->hsc_seb_res);

	hsc->hsc_etx_rid = 1;
	hsc->hsc_etx_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &hsc->hsc_etx_rid, 0, ~0, 1, RF_ACTIVE);
	if (hsc->hsc_etx_res == NULL) {
		device_printf(dev, "cannot map ETX registers\n");
		goto fail_seb_res;
	}
	sc->sc_etxt = rman_get_bustag(hsc->hsc_etx_res);
	sc->sc_etxh = rman_get_bushandle(hsc->hsc_etx_res);

	hsc->hsc_erx_rid = 2;
	hsc->hsc_erx_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &hsc->hsc_erx_rid, 0, ~0, 1, RF_ACTIVE);
	if (hsc->hsc_erx_res == NULL) {
		device_printf(dev, "cannot map ERX registers\n");
		goto fail_etx_res;
	}
	sc->sc_erxt = rman_get_bustag(hsc->hsc_erx_res);
	sc->sc_erxh = rman_get_bushandle(hsc->hsc_erx_res);

	hsc->hsc_mac_rid = 3;
	hsc->hsc_mac_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &hsc->hsc_mac_rid, 0, ~0, 1, RF_ACTIVE);
	if (hsc->hsc_mac_res == NULL) {
		device_printf(dev, "cannot map MAC registers\n");
		goto fail_erx_res;
	}
	sc->sc_mact = rman_get_bustag(hsc->hsc_mac_res);
	sc->sc_mach = rman_get_bushandle(hsc->hsc_mac_res);

	/*
	 * At least on some HMEs, the MIF registers seem to be inside the MAC
	 * range, so map try to kluge around it.
	 */
	hsc->hsc_mif_rid = 4;
	hsc->hsc_mif_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
	    &hsc->hsc_mif_rid, 0, ~0, 1, RF_ACTIVE);
	if (hsc->hsc_mif_res == NULL) {
		if (bus_get_resource(dev, SYS_RES_MEMORY, hsc->hsc_mif_rid,
		    &start, &count) != 0) {
			device_printf(dev, "cannot get MIF registers\n");
			goto fail_mac_res;
		}
		if (start < rman_get_start(hsc->hsc_mac_res) ||
		    start + count - 1 > rman_get_end(hsc->hsc_mac_res)) {
			device_printf(dev, "cannot move MIF registers to MAC "
			    "bank\n");
			goto fail_mac_res;
		}
		sc->sc_mift = sc->sc_mact;
		sc->sc_mifh = sc->sc_mach;
		sc->sc_mifo = sc->sc_maco + start -
		    rman_get_start(hsc->hsc_mac_res);
	} else {
		sc->sc_mift = rman_get_bustag(hsc->hsc_mif_res);
		sc->sc_mifh = rman_get_bushandle(hsc->hsc_mif_res);
	}

	hsc->hsc_irid = 0;
	hsc->hsc_ires = bus_alloc_resource(dev, SYS_RES_IRQ, &hsc->hsc_irid, 0,
	    ~0, 1, RF_SHAREABLE | RF_ACTIVE);
	if (hsc->hsc_ires == NULL) {
		device_printf(dev, "could not allocate interrupt\n");
		error = ENXIO;
		goto fail_mif_res;
	}


	OF_getetheraddr(dev, sc->sc_arpcom.ac_enaddr);

	burst = sbus_get_burstsz(dev);
	/* Translate into plain numerical format */
	sc->sc_burst =  (burst & SBUS_BURST_32) ? 32 :
	    (burst & SBUS_BURST_16) ? 16 : 0;

	sc->sc_pci = 0;	/* XXX: should all be done in bus_dma. */
	sc->sc_dev = dev;

	if ((error = hme_config(sc)) != 0) {
		device_printf(dev, "could not be configured\n");
		goto fail_ires;
	}


	if ((error = bus_setup_intr(dev, hsc->hsc_ires, INTR_TYPE_NET, hme_intr,
	     sc, &hsc->hsc_ih)) != 0) {
		device_printf(dev, "couldn't establish interrupt\n");
		goto fail_ires;
	}
	return (0);

fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ, hsc->hsc_irid, hsc->hsc_ires);
fail_mif_res:
	if (hsc->hsc_mif_res != NULL) {
		bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_mif_rid,
		    hsc->hsc_mif_res);
	}
fail_mac_res:
	bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_mac_rid,
	    hsc->hsc_mac_res);
fail_erx_res:
	bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_erx_rid,
	    hsc->hsc_erx_res);
fail_etx_res:
	bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_etx_rid,
	    hsc->hsc_etx_res);
fail_seb_res:
	bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_seb_rid,
	    hsc->hsc_seb_res);
	return (ENXIO);
}
Esempio n. 19
0
/*---------------------------------------------------------------------------*
 *	isic_probe_s016 - probe for Teles S0/16 and compatibles
 *---------------------------------------------------------------------------*/
int
isic_probe_s016(device_t dev)
{
	size_t unit = device_get_unit(dev);	/* get unit */
	struct l1_softc *sc = 0;		/* softc */
	void *ih = 0;				/* dummy */
	u_int8_t b0,b1,b2;			/* for signature */
	bus_space_tag_t    t;			/* bus things */
	bus_space_handle_t h;

	/* check max unit range */

	if(unit >= ISIC_MAXUNIT)
	{
		printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16!\n",
				unit, unit);
		return(ENXIO);	
	}

	sc = &l1_sc[unit];			/* get pointer to softc */
	sc->sc_unit = unit;			/* set unit */

	/* see if an io base was supplied */

	if(!(sc->sc_resources.io_base[0] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
	                                   &sc->sc_resources.io_rid[0],
	                                   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not allocate i/o port for Teles S0/16.\n", unit);
		return(ENXIO);
	}

	sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);

	/*
	 * check if the provided io port is valid
	 */

	switch(sc->sc_port)
	{
		case 0xd80:
		case 0xe80:
		case 0xf80:
			break;

		default:
			printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16!\n",
				unit, sc->sc_port);
			isic_detach_common(dev);
			return(ENXIO);
			break;
	}

	/* allocate memory resource */

	if(!(sc->sc_resources.mem =
			bus_alloc_resource(dev, SYS_RES_MEMORY,
					&sc->sc_resources.mem_rid,
					0ul, ~0ul, TELES_S016_MEMSIZE,
					RF_ACTIVE)))
	{
		printf("isic%d: Could not allocate memory for Teles S0/16.\n", unit);
		isic_detach_common(dev);
		return(ENXIO);
	}

	/* 
	 * get virtual addr.
	 */
	sc->sc_vmem_addr = rman_get_virtual(sc->sc_resources.mem);

	/*
	 * check for valid adresses
	 */
	switch(kvtop(sc->sc_vmem_addr))
	{
		case 0xc0000:
		case 0xc2000:
		case 0xc4000:
		case 0xc6000:
		case 0xc8000:
		case 0xca000:
		case 0xcc000:
		case 0xce000:
		case 0xd0000:
		case 0xd2000:
		case 0xd4000:
		case 0xd6000:
		case 0xd8000:
		case 0xda000:
		case 0xdc000:
		case 0xde000:
			break;

		default:
			printf("isic%d: Error, invalid memory address 0x%lx for Teles S0/16!\n",
				unit, kvtop(sc->sc_vmem_addr));
			isic_detach_common(dev);
			return(ENXIO);
			break;
	}		
	
	/* setup ISAC access routines */

	sc->clearirq = NULL;

	sc->readreg = tels016_read_reg;
	sc->writereg = tels016_write_reg;

	sc->readfifo = tels016_read_fifo;
	sc->writefifo = tels016_write_fifo;

	/* setup card type */
	sc->sc_cardtyp = CARD_TYPEP_16;

	/* setup IOM bus type */
	
	sc->sc_bustyp = BUS_TYPE_IOM1;

	sc->sc_ipac = 0;
	sc->sc_bfifolen = HSCX_FIFO_LEN;

	/* setup ISAC base addr, though we don't really need it */
	
	ISAC_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x100);

	/* setup HSCX base addr */
	
	HSCX_A_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x180);
	HSCX_B_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x1c0);

	t = rman_get_bustag(sc->sc_resources.io_base[0]);
	h = rman_get_bushandle(sc->sc_resources.io_base[0]);

	/* get signature bytes */
	b0 = bus_space_read_1(t, h, 0);
	b1 = bus_space_read_1(t, h, 1);
	b2 = bus_space_read_1(t, h, 2);

	/* check signature bytes */
	if(b0 != 0x51)
	{
		printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16!\n",
			unit, b0);
		isic_detach_common(dev);
		return(ENXIO);
	}
	
	if(b1 != 0x93)
	{
		printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16!\n",
			unit, b1);
		isic_detach_common(dev);
		return(ENXIO);
	}
	
	if((b2 != 0x1e) && (b2 != 0x1f))
	{
		printf("isic%d: Error, signature 3 0x%x != 0x1e or 0x1f for Teles S0/16!\n",
			unit, b2);
		isic_detach_common(dev);
		return(ENXIO);
	}

	/* get our irq */

	if(!(sc->sc_resources.irq =
			bus_alloc_resource(dev, SYS_RES_IRQ,
						&sc->sc_resources.irq_rid,
						0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not allocate irq for Teles S0/16.\n", unit);
		isic_detach_common(dev);
		return ENXIO;
	}

	/* register interupt routine */

	bus_setup_intr(dev, sc->sc_resources.irq,
			INTR_TYPE_NET,
			(void(*)(void *))(isicintr),
			sc, &ih);

	/* get the irq number */
	
	sc->sc_irq = rman_get_start(sc->sc_resources.irq);

	/* check IRQ validity */

	if((intr_no[sc->sc_irq]) == 1)
	{
		printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16!\n",
			unit, sc->sc_irq);
		isic_detach_common(dev);
		return(ENXIO);
	}
	
	return (0);
}
Esempio n. 20
0
static int
zbpci_attach(device_t dev)
{
	int n, rid, size;
	vm_offset_t va;
	struct resource *res;
	
	/*
	 * Reserve the physical memory window used to map PCI I/O space.
	 */
	rid = 0;
	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
				 PCI_IOSPACE_ADDR,
				 PCI_IOSPACE_ADDR + PCI_IOSPACE_SIZE - 1,
				 PCI_IOSPACE_SIZE, 0);
	if (res == NULL)
		panic("Cannot allocate resource for PCI I/O space mapping.");

	port_rman.rm_start = 0;
	port_rman.rm_end = PCI_IOSPACE_SIZE - 1;
	port_rman.rm_type = RMAN_ARRAY;
	port_rman.rm_descr = "PCI I/O ports";
	if (rman_init(&port_rman) != 0 ||
	    rman_manage_region(&port_rman, 0, PCI_IOSPACE_SIZE - 1) != 0)
		panic("%s: port_rman", __func__);

	/*
	 * Reserve the physical memory that is used to read/write to the
	 * pci config space but don't activate it. We are using a page worth
	 * of KVA as a window over this region.
	 */
	rid = 1;
	size = (PCI_BUSMAX + 1) * (PCI_SLOTMAX + 1) * (PCI_FUNCMAX + 1) * 256;
	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, CFG_PADDR_BASE,
				 CFG_PADDR_BASE + size - 1, size, 0);
	if (res == NULL)
		panic("Cannot allocate resource for config space accesses.");

	/*
	 * Allocate the entire "match bit lanes" address space.
	 */
#if _BYTE_ORDER == _BIG_ENDIAN
	rid = 2;
	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 
				 PCI_MATCH_BIT_LANES_START,
				 PCI_MATCH_BIT_LANES_END,
				 PCI_MATCH_BIT_LANES_SIZE, 0);
	if (res == NULL)
		panic("Cannot allocate resource for pci match bit lanes.");
#endif	/* _BYTE_ORDER ==_BIG_ENDIAN */

	/*
	 * Allocate KVA for accessing PCI config space.
	 */
	va = kva_alloc(PAGE_SIZE * mp_ncpus);
	if (va == 0) {
		device_printf(dev, "Cannot allocate virtual addresses for "
				   "config space access.\n");
		return (ENOMEM);
	}

	for (n = 0; n < mp_ncpus; ++n)
		zbpci_config_space[n].vaddr = va + n * PAGE_SIZE;

	/*
	 * Sibyte has the PCI bus hierarchy rooted at bus 0 and HT-PCI
	 * hierarchy rooted at bus 1.
	 */
	if (device_add_child(dev, "pci", 0) == NULL)
		panic("zbpci_attach: could not add pci bus 0.\n");

	if (device_add_child(dev, "pci", 1) == NULL)
		panic("zbpci_attach: could not add pci bus 1.\n");

	if (bootverbose)
		device_printf(dev, "attached.\n");

	return (bus_generic_attach(dev));
}
Esempio n. 21
0
static int
rp_probe(device_t dev)
{
	int unit;
	CONTROLLER_t *controller;
	int num_aiops;
	CONTROLLER_t *ctlp;
	int retval;

	/*
	 * We have no PnP RocketPort cards.
	 * (At least according to LINT)
	 */
	if (isa_get_logicalid(dev) != 0)
		return (ENXIO);

	/* We need IO port resource to configure an ISA device. */
	if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 0)
		return (ENXIO);

	unit = device_get_unit(dev);
	if (unit >= 4) {
		device_printf(dev, "rpprobe: unit number %d invalid.\n", unit);
		return (ENXIO);
	}
	device_printf(dev, "probing for RocketPort(ISA) unit %d.\n", unit);

	ctlp = device_get_softc(dev);
	bzero(ctlp, sizeof(*ctlp));
	ctlp->dev = dev;
	ctlp->aiop2rid = rp_isa_aiop2rid;
	ctlp->aiop2off = rp_isa_aiop2off;
	ctlp->ctlmask = rp_isa_ctlmask;

	/* The IO ports of AIOPs for an ISA controller are discrete. */
	ctlp->io_num = 1;
	ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO);
	ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO);
	if (ctlp->io_rid == NULL || ctlp->io == NULL) {
		device_printf(dev, "rp_attach: Out of memory.\n");
		retval = ENOMEM;
		goto nogo;
	}

	ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT | M_ZERO);
	if (ctlp->bus_ctlp == NULL) {
		device_printf(dev, "rp_attach: Out of memory.\n");
		retval = ENOMEM;
		goto nogo;
	}

	ctlp->io_rid[0] = 0;
	if (rp_controller != NULL) {
		controller = rp_controller;
		ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x40, RF_ACTIVE);
	} else {
		controller = rp_controller = ctlp;
		ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x44, RF_ACTIVE);
	}
	if (ctlp->io[0] == NULL) {
		device_printf(dev, "rp_attach: Resource not available.\n");
		retval = ENXIO;
		goto nogo;
	}

	num_aiops = sInitController(ctlp,
				controller,
				MAX_AIOPS_PER_BOARD, 0,
				FREQ_DIS, 0);
	if (num_aiops <= 0) {
		device_printf(dev, "board%d init failed.\n", unit);
		retval = ENXIO;
		goto nogo;
	}

	if (rp_controller == NULL)
		rp_controller = controller;
	rp_nisadevs++;

	device_set_desc(dev, "RocketPort ISA");

	return (0);

nogo:
	rp_isareleaseresource(ctlp);

	return (retval);
}
Esempio n. 22
0
/**
 * Configure common hardware for all interfaces
 */
static void cvm_oct_configure_common_hw(device_t bus)
{
	struct octebus_softc *sc;
	int pko_queues;
	int error;
	int rid;

        sc = device_get_softc(bus);

	/* Setup the FPA */
	cvmx_fpa_enable();
	cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
			     num_packet_buffers);
	cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
			     num_packet_buffers);
	if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) {
		/*
		 * If the FPA uses different pools for output buffers and
		 * packets, size the output buffer pool based on the number
		 * of PKO queues.
		 */
		if (OCTEON_IS_MODEL(OCTEON_CN38XX))
			pko_queues = 128;
		else if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
			pko_queues = 32;
		else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
			pko_queues = 32;
		else
			pko_queues = 256;

		cvm_oct_num_output_buffers = 4 * pko_queues;
		cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
				     CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
				     cvm_oct_num_output_buffers);
	}

	if (USE_RED)
		cvmx_helper_setup_red(num_packet_buffers/4,
				      num_packet_buffers/8);

	/* Enable the MII interface */
	if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM)
		cvmx_write_csr(CVMX_SMI_EN, 1);

	/* Register an IRQ hander for to receive POW interrupts */
        rid = 0;
        sc->sc_rx_irq = bus_alloc_resource(bus, SYS_RES_IRQ, &rid,
					   OCTEON_IRQ_WORKQ0 + pow_receive_group,
					   OCTEON_IRQ_WORKQ0 + pow_receive_group,
					   1, RF_ACTIVE);
        if (sc->sc_rx_irq == NULL) {
                device_printf(bus, "could not allocate workq irq");
		return;
        }

        error = bus_setup_intr(bus, sc->sc_rx_irq, INTR_TYPE_NET | INTR_MPSAFE,
			       cvm_oct_do_interrupt, NULL, cvm_oct_device,
			       &sc->sc_rx_intr_cookie);
        if (error != 0) {
                device_printf(bus, "could not setup workq irq");
		return;
        }


#ifdef SMP
	{
		cvmx_ciu_intx0_t en;
		int core;

		CPU_FOREACH(core) {
			if (core == PCPU_GET(cpuid))
				continue;

			en.u64 = cvmx_read_csr(CVMX_CIU_INTX_EN0(core*2));
			en.s.workq |= (1<<pow_receive_group);
			cvmx_write_csr(CVMX_CIU_INTX_EN0(core*2), en.u64);
		}
	}
#endif
}
Esempio n. 23
0
void
cpu_initclocks(void)
{
	struct s3c24x0_softc *sc = (struct s3c24x0_softc *)s3c2xx0_softc;
	long tc;
	struct resource *irq;
	int rid = 0;
	void *ihl;
	int err, prescaler;
	int pclk = s3c2xx0_softc->sc_pclk;
	bus_space_tag_t iot = sc->sc_sx.sc_iot;
	bus_space_handle_t ioh = sc->sc_timer_ioh;
	uint32_t  reg;
	device_t dev = timer_softc.dev;

	/* We have already been initialized */
	if (timer4_reload_value != 0)
		return;

#define	time_constant(hz)	(TIMER_FREQUENCY(pclk) /(hz)/ prescaler)
#define calc_time_constant(hz)					\
	do {							\
		prescaler = 1;					\
		do {						\
			++prescaler;				\
			tc = time_constant(hz);			\
		} while( tc > 65536 );				\
	} while(0)


	/* Use the channels 4 and 3 for hardclock and statclock, respectively */

	/* stop all timers */
	bus_space_write_4(iot, ioh, TIMER_TCON, 0);

	/* calc suitable prescaler value */
	calc_time_constant(hz);

	timer4_prescaler = prescaler;
	timer4_reload_value = TIMER_FREQUENCY(pclk) / hz / prescaler;
	timer4_mseccount = TIMER_FREQUENCY(pclk)/timer4_prescaler/1000 ;

	bus_space_write_4(iot, ioh, TIMER_TCNTB(4),
	    ((prescaler - 1) << 16) | (timer4_reload_value - 1));

	printf("clock: hz=%d PCLK=%d prescaler=%d tc=%ld\n",
	    hz, pclk, prescaler, tc);

	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, S3C24X0_INT_TIMER4,
		S3C24X0_INT_TIMER4, 1, RF_ACTIVE);
	if (!irq)
		panic("Unable to allocate the clock irq handler.\n");

	err = bus_setup_intr(dev, irq, INTR_TYPE_CLK | INTR_FAST,
	    clock_intr, NULL, NULL, &ihl);
	if (err != 0)
		panic("Unable to setup the clock irq handler.\n");

	/* set prescaler1 */
	reg = bus_space_read_4(iot, ioh, TIMER_TCFG0);
	bus_space_write_4(iot, ioh, TIMER_TCFG0,
			  (reg & ~0xff00) | ((prescaler-1) << 8));

	/* divider 1/16 for ch #4 */
	reg = bus_space_read_4(iot, ioh, TIMER_TCFG1);
	bus_space_write_4(iot, ioh, TIMER_TCFG1,
			  (reg & ~(TCFG1_MUX_MASK(4))) |
			  (TCFG1_MUX_DIV16 << TCFG1_MUX_SHIFT(4)) );


	/* start timers */
	reg = bus_space_read_4(iot, ioh, TIMER_TCON);
	reg &= ~(TCON_MASK(4));

	/* load the time constant */
	bus_space_write_4(iot, ioh, TIMER_TCON, reg | TCON_MANUALUPDATE(4));
	/* set auto reload and start */
	bus_space_write_4(iot, ioh, TIMER_TCON, reg |
	    TCON_AUTORELOAD(4) | TCON_START(4) );

	s3c24x0_timer_timecounter.tc_frequency = TIMER_FREQUENCY(pclk) /
	    timer4_prescaler;
	tc_init(&s3c24x0_timer_timecounter);
}
static int
bt3c_pccard_attach(device_t dev)
{
	bt3c_softc_p	sc = (bt3c_softc_p) device_get_softc(dev);

	/* Allocate I/O ports */
	sc->iobase_rid = 0;
	sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->iobase_rid, 
			0, ~0, 8, RF_ACTIVE);
	if (sc->iobase == NULL) {
		device_printf(dev, "Could not allocate I/O ports\n");
		goto bad;
	}
	sc->iot = rman_get_bustag(sc->iobase);
	sc->ioh = rman_get_bushandle(sc->iobase);

	/* Allocate IRQ */
	sc->irq_rid = 0;
	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
			RF_ACTIVE);
	if (sc->irq == NULL) {
		device_printf(dev, "Could not allocate IRQ\n");
		goto bad;
	}

	sc->irq_cookie = NULL;
	if (bus_setup_intr(dev, sc->irq, 0, bt3c_intr, sc,
			&sc->irq_cookie, NULL) != 0) {
		device_printf(dev, "Could not setup ISR\n");
		goto bad;
	}

	/* Attach handler to TTY SWI thread */
	sc->ith = NULL;
	sc->ith = register_swi_mp(SWI_TTY, bt3c_swi_intr, sc,
	    device_get_nameunit(dev), NULL, -1);
	if (sc->ith == NULL) {
		device_printf(dev, "Could not setup SWI ISR\n");
		goto bad;
	}

	/* Create Netgraph node */
	if (ng_make_node_common(&typestruct, &sc->node) != 0) {
		device_printf(dev, "Could not create Netgraph node\n");
		sc->node = NULL;
		goto bad;
	}

	/* Name Netgraph node */
	if (ng_name_node(sc->node, device_get_nameunit(dev)) != 0) {
		device_printf(dev, "Could not name Netgraph node\n");
		NG_NODE_UNREF(sc->node);
		sc->node = NULL;
		goto bad;
	}

	sc->dev = dev;
	sc->debug = NG_BT3C_WARN_LEVEL;

	sc->inq.ifq_maxlen = sc->outq.ifq_maxlen = BT3C_DEFAULTQLEN;

	sc->state = NG_BT3C_W4_PKT_IND;
	sc->want = 1;

	NG_NODE_SET_PRIVATE(sc->node, sc);

	return (0);
bad:
	if (sc->ith != NULL) {
		unregister_swi(sc->ith, SWI_TTY, -1);
		sc->ith = NULL;
	}

	if (sc->irq != NULL) {
		if (sc->irq_cookie != NULL)
			bus_teardown_intr(dev, sc->irq, sc->irq_cookie);

		bus_release_resource(dev, SYS_RES_IRQ,
			sc->irq_rid, sc->irq);

		sc->irq = NULL;
		sc->irq_rid = 0;
	}

	if (sc->iobase != NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT,
			sc->iobase_rid, sc->iobase);

		sc->iobase = NULL;
		sc->iobase_rid = 0;
	}

	return (ENXIO);
} /* bt3c_pccacd_attach */
Esempio n. 25
0
/***************************************************************************
Function: sInitController
Purpose:  Initialization of controller global registers and controller
	  structure.
Call:	  sInitController(CtlP,MudbacCtlP,AiopNum,
			  IRQNum,Frequency,PeriodicOnly)
	  CONTROLLER_T *CtlP; Ptr to controller structure
	  CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
	  int AiopNum; Number of Aiops
	  int IRQNum; Interrupt Request number.  Can be any of the following:
			 0: Disable global interrupts
			 3: IRQ 3
			 4: IRQ 4
			 5: IRQ 5
			 9: IRQ 9
			 10: IRQ 10
			 11: IRQ 11
			 12: IRQ 12
			 15: IRQ 15
	  Byte_t Frequency: A flag identifying the frequency
		   of the periodic interrupt, can be any one of the following:
		      FREQ_DIS - periodic interrupt disabled
		      FREQ_137HZ - 137 Hertz
		      FREQ_69HZ - 69 Hertz
		      FREQ_34HZ - 34 Hertz
		      FREQ_17HZ - 17 Hertz
		      FREQ_9HZ - 9 Hertz
		      FREQ_4HZ - 4 Hertz
		   If IRQNum is set to 0 the Frequency parameter is
		   overidden, it is forced to a value of FREQ_DIS.
	  int PeriodicOnly: TRUE if all interrupts except the periodic
			       interrupt are to be blocked.
			    FALSE is both the periodic interrupt and
			       other channel interrupts are allowed.
			    If IRQNum is set to 0 the PeriodicOnly parameter is
			       overidden, it is forced to a value of FALSE.
Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
	       initialization failed.

Comments:
	  If periodic interrupts are to be disabled but AIOP interrupts
	  are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.

	  If interrupts are to be completely disabled set IRQNum to 0.

	  Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
	  invalid combination.

	  This function performs initialization of global interrupt modes,
	  but it does not actually enable global interrupts.  To enable
	  and disable global interrupts use functions sEnGlobalInt() and
	  sDisGlobalInt().  Enabling of global interrupts is normally not
	  done until all other initializations are complete.

	  Even if interrupts are globally enabled, they must also be
	  individually enabled for each channel that is to generate
	  interrupts.

Warnings: No range checking on any of the parameters is done.

	  No context switches are allowed while executing this function.

	  After this function all AIOPs on the controller are disabled,
	  they can be enabled with sEnAiop().
*/
static int
sInitController(	CONTROLLER_T *CtlP,
			CONTROLLER_T *MudbacCtlP,
			int AiopNum,
			int IRQNum,
			Byte_t Frequency,
			int PeriodicOnly)
{
	int		i;
	int		ctl_base, aiop_base, aiop_size;

	CtlP->CtlID = CTLID_0001;		/* controller release 1 */

	ISACTL(CtlP)->MBaseIO = rp_nisadevs;
	if (MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] != NULL) {
		ISACTL(CtlP)->MReg0IO = 0x40 + 0;
		ISACTL(CtlP)->MReg1IO = 0x40 + 1;
		ISACTL(CtlP)->MReg2IO = 0x40 + 2;
		ISACTL(CtlP)->MReg3IO = 0x40 + 3;
	} else {
		MudbacCtlP->io_rid[ISACTL(CtlP)->MBaseIO] = ISACTL(CtlP)->MBaseIO;
		ctl_base = rman_get_start(MudbacCtlP->io[0]) + 0x40 + 0x400 * rp_nisadevs;
		MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] = bus_alloc_resource(MudbacCtlP->dev, SYS_RES_IOPORT, &CtlP->io_rid[ISACTL(CtlP)->MBaseIO], ctl_base, ctl_base + 3, 4, RF_ACTIVE);
		ISACTL(CtlP)->MReg0IO = 0;
		ISACTL(CtlP)->MReg1IO = 1;
		ISACTL(CtlP)->MReg2IO = 2;
		ISACTL(CtlP)->MReg3IO = 3;
	}
#if 1
	ISACTL(CtlP)->MReg2 = 0;			/* interrupt disable */
	ISACTL(CtlP)->MReg3 = 0;			/* no periodic interrupts */
#else
	if(sIRQMap[IRQNum] == 0)		/* interrupts globally disabled */
	{
		ISACTL(CtlP)->MReg2 = 0;		/* interrupt disable */
		ISACTL(CtlP)->MReg3 = 0;		/* no periodic interrupts */
	}
	else
	{
		ISACTL(CtlP)->MReg2 = sIRQMap[IRQNum];	/* set IRQ number */
		ISACTL(CtlP)->MReg3 = Frequency;	/* set frequency */
		if(PeriodicOnly)		/* periodic interrupt only */
		{
			ISACTL(CtlP)->MReg3 |= PERIODIC_ONLY;
		}
	}
#endif
	rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2);
	rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3);
	sControllerEOI(MudbacCtlP,CtlP);			/* clear EOI if warm init */

	/* Init AIOPs */
	CtlP->NumAiop = 0;
	for(i=0; i < AiopNum; i++)
	{
		if (CtlP->io[i] == NULL) {
			CtlP->io_rid[i] = i;
			aiop_base = rman_get_start(CtlP->io[0]) + 0x400 * i;
			if (rp_nisadevs == 0)
				aiop_size = 0x44;
			else
				aiop_size = 0x40;
			CtlP->io[i] = bus_alloc_resource(CtlP->dev, SYS_RES_IOPORT, &CtlP->io_rid[i], aiop_base, aiop_base + aiop_size - 1, aiop_size, RF_ACTIVE);
		} else
			aiop_base = rman_get_start(CtlP->io[i]);
		rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,
			    ISACTL(CtlP)->MReg2IO,
			    ISACTL(CtlP)->MReg2 | (i & 0x03));	/* AIOP index */
		rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,
			    ISACTL(CtlP)->MReg0IO,
			    (Byte_t)(aiop_base >> 6));		/* set up AIOP I/O in MUDBAC */
		sEnAiop(MudbacCtlP,CtlP,i);			/* enable the AIOP */

		CtlP->AiopID[i] = sReadAiopID(CtlP, i);		/* read AIOP ID */
		if(CtlP->AiopID[i] == AIOPID_NULL)		/* if AIOP does not exist */
		{
			sDisAiop(MudbacCtlP,CtlP,i);		/* disable AIOP */
			bus_release_resource(CtlP->dev, SYS_RES_IOPORT, CtlP->io_rid[i], CtlP->io[i]);
			CtlP->io[i] = NULL;
			break;					/* done looking for AIOPs */
		}

		CtlP->AiopNumChan[i] = sReadAiopNumChan(CtlP, i);	/* num channels in AIOP */
		rp_writeaiop2(CtlP,i,_INDX_ADDR,_CLK_PRE);	/* clock prescaler */
		rp_writeaiop1(CtlP,i,_INDX_DATA,CLOCK_PRESC);
		CtlP->NumAiop++;				/* bump count of AIOPs */
		sDisAiop(MudbacCtlP,CtlP,i);			/* disable AIOP */
	}

	if(CtlP->NumAiop == 0)
		return(-1);
	else
		return(CtlP->NumAiop);
}
Esempio n. 26
0
/*---------------------------------------------------------------------------*
 *	PCI attach
 *---------------------------------------------------------------------------*/
static int
iwic_pci_attach(device_t dev)
{
	unsigned short iobase;
	struct iwic_softc *sc;
	void *ih = 0;
	int unit = device_get_unit(dev);
	struct iwic_bchan *bchan;
	
	/* check max unit range */
	
	if(unit >= IWIC_MAXUNIT)
	{
		printf("iwic%d: Error, unit %d >= IWIC_MAXUNIT!\n", unit, unit);
		return(ENXIO);	
	}	

	sc = iwic_find_sc(unit);	/* get softc */	
	
	sc->sc_unit = unit;

	/* use the i/o mapped base address */
	
	sc->sc_resources.io_rid[0] = BADDR1;
	
	if(!(sc->sc_resources.io_base[0] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
						&sc->sc_resources.io_rid[0],
						0UL, ~0UL, 1, RF_ACTIVE)))
	{
		printf("iwic%d: Couldn't alloc io port!\n", unit);
		return(ENXIO);                                       
	}

	iobase = rman_get_start(sc->sc_resources.io_base[0]);

	if(!(sc->sc_resources.irq =
			bus_alloc_resource(dev, SYS_RES_IRQ,
					   &sc->sc_resources.irq_rid,
					   0UL, ~0UL, 1, RF_SHAREABLE|RF_ACTIVE)))
	{
		printf("iwic%d: Couldn't alloc irq!\n",unit);
		return(ENXIO);                                       
	}
	
	/* setup card type */
	
	sc->sc_cardtyp = CARD_TYPEP_WINB6692;
	sc->sc_iobase = (u_int32_t) iobase;
	sc->sc_trace = TRACE_OFF;
	sc->sc_I430state = ST_F3N;	/* Deactivated */
	sc->enabled = FALSE;
	
	if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
				(void(*)(void*))iwic_pci_intr,
				sc, &ih))
	{
		printf("iwic%d: Couldn't set up irq!\n", unit);
		return(ENXIO);
	}

	/* disable interrupts */
	IWIC_WRITE(sc, IMASK, 0xff);

	iwic_dchan_init(sc);

	bchan = &sc->sc_bchan[IWIC_BCH_A];
	bchan->unit = unit;
	bchan->offset = B1_CHAN_OFFSET;
	bchan->channel = IWIC_BCH_A;
	bchan->state = ST_IDLE;
		
	iwic_bchannel_setup(unit, IWIC_BCH_A, BPROT_NONE, 0);

	bchan = &sc->sc_bchan[IWIC_BCH_B];
	bchan->unit = unit;
	bchan->offset = B2_CHAN_OFFSET;
	bchan->channel = IWIC_BCH_B;
	bchan->state = ST_IDLE;
	
	iwic_bchannel_setup(unit, IWIC_BCH_B, BPROT_NONE, 0);

	iwic_init_linktab(sc);
	
	if(bootverbose)
	{
		int ver = IWIC_READ(sc, D_RBCH);
		printf("iwic%d: W6692 chip version = %d\n", unit, D_RBCH_VN(ver));
	}

	i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &iwic_l1mux_func);

	IWIC_READ(sc, ISTA);

	/* Enable interrupts */
	IWIC_WRITE(sc, IMASK, IMASK_XINT0 | IMASK_XINT1);

	return(0);
}
Esempio n. 27
0
static int
cs4281_pci_attach(device_t dev)
{
    struct sc_info *sc;
    struct ac97_info *codec = NULL;
    u_int32_t data;
    char status[SND_STATUSLEN];

    sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
    sc->dev = dev;
    sc->type = pci_get_devid(dev);

    data = pci_read_config(dev, PCIR_COMMAND, 2);
    data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
    pci_write_config(dev, PCIR_COMMAND, data, 2);

    if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
	/* Reset the power state. */
	device_printf(dev, "chip is in D%d power mode "
		      "-- setting to D0\n", pci_get_powerstate(dev));

	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
    }

    sc->regid   = PCIR_BAR(0);
    sc->regtype = SYS_RES_MEMORY;
    sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid,
				 0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE);
    if (!sc->reg) {
	sc->regtype = SYS_RES_IOPORT;
	sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid,
				     0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE);
	if (!sc->reg) {
	    device_printf(dev, "unable to allocate register space\n");
	    goto bad;
	}
    }
    sc->st = rman_get_bustag(sc->reg);
    sc->sh = rman_get_bushandle(sc->reg);

    sc->memid = PCIR_BAR(1);
    sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->memid, 0,
				 ~0, CS4281PCI_BA1_SIZE, RF_ACTIVE);
    if (sc->mem == NULL) {
	device_printf(dev, "unable to allocate fifo space\n");
	goto bad;
    }

    sc->irqid = 0;
    sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
				     RF_ACTIVE | RF_SHAREABLE);
    if (!sc->irq) {
	device_printf(dev, "unable to allocate interrupt\n");
	goto bad;
    }

    if (snd_setup_intr(dev, sc->irq, 0, cs4281_intr, sc, &sc->ih)) {
	device_printf(dev, "unable to setup interrupt\n");
	goto bad;
    }

    sc->bufsz = pcm_getbuffersize(dev, 4096, CS4281_DEFAULT_BUFSZ, 65536);

    if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
			   /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
			   /*highaddr*/BUS_SPACE_MAXADDR,
			   /*filter*/NULL, /*filterarg*/NULL,
			   /*maxsize*/sc->bufsz, /*nsegments*/1,
			   /*maxsegz*/0x3ffff,
			   /*flags*/0,
			   &sc->parent_dmat) != 0) {
	device_printf(dev, "unable to create dma tag\n");
	goto bad;
    }

    /* power up */
    cs4281_power(sc, 0);

    /* init chip */
    if (cs4281_init(sc) == -1) {
	device_printf(dev, "unable to initialize the card\n");
	goto bad;
    }

    /* create/init mixer */
    codec = AC97_CREATE(dev, sc, cs4281_ac97);
    if (codec == NULL)
        goto bad;

    mixer_init(dev, ac97_getmixerclass(), codec);

    if (pcm_register(dev, sc, 1, 1))
	goto bad;

    pcm_addchan(dev, PCMDIR_PLAY, &cs4281chan_class, sc);
    pcm_addchan(dev, PCMDIR_REC, &cs4281chan_class, sc);

    ksnprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld %s",
	     (sc->regtype == SYS_RES_IOPORT)? "io" : "memory",
	     rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_cs4281));
    pcm_setstatus(dev, status);

    return 0;

 bad:
    if (codec)
	ac97_destroy(codec);
    if (sc->reg)
	bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
    if (sc->mem)
	bus_release_resource(dev, SYS_RES_MEMORY, sc->memid, sc->mem);
    if (sc->ih)
	bus_teardown_intr(dev, sc->irq, sc->ih);
    if (sc->irq)
	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
    if (sc->parent_dmat)
	bus_dma_tag_destroy(sc->parent_dmat);
    kfree(sc, M_DEVBUF);

    return ENXIO;
}
Esempio n. 28
0
/*
 * Check if the device can be found at the port given
 */
static int
aha_isa_probe(device_t dev)
{
	/*
	 * find unit and check we have that many defined
	 */
	struct	aha_softc *aha = device_get_softc(dev);
	int	error;
	u_long	port_start;
	struct resource *port_res;
	int	port_rid;
	int	drq;
	int	irq;
	config_data_t config_data;

	aha->dev = dev;
	/* Check isapnp ids */
	if (ISA_PNP_PROBE(device_get_parent(dev), dev, aha_ids) == ENXIO)
		return (ENXIO);

	port_rid = 0;
	port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid,
	    0, ~0, AHA_NREGS, RF_ACTIVE);

	if (port_res == NULL)
		return (ENXIO);

	port_start = rman_get_start(port_res);
	aha_alloc(aha, device_get_unit(dev), rman_get_bustag(port_res),
	    rman_get_bushandle(port_res));

	/* See if there is really a card present */
	if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
		aha_free(aha);
		bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res);
		return (ENXIO);
	}

	/*
	 * Determine our IRQ, and DMA settings and
	 * export them to the configuration system.
	 */
	error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
	    (uint8_t*)&config_data, sizeof(config_data), DEFAULT_CMD_TIMEOUT);

	if (error != 0) {
		device_printf(dev, "Could not determine IRQ or DMA "
		    "settings for adapter at %#jx.  Failing probe\n",
		    (uintmax_t)port_start);
		aha_free(aha);
		bus_release_resource(dev, SYS_RES_IOPORT, port_rid,
		    port_res);
		return (ENXIO);
	}

	bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res);

	switch (config_data.dma_chan) {
	case DMA_CHAN_5:
		drq = 5;
		break;
	case DMA_CHAN_6:
		drq = 6;
		break;
	case DMA_CHAN_7:
		drq = 7;
		break;
	default:
		device_printf(dev, "Invalid DMA setting for adapter at %#jx.",
		    (uintmax_t)port_start);
		return (ENXIO);
	}
	error = bus_set_resource(dev, SYS_RES_DRQ, 0, drq, 1);
	if (error)
		return error;

	irq = ffs(config_data.irq) + 8;
	error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
	return (error);
}
Esempio n. 29
0
static int
iavc_isa_probe(device_t dev)
{
	struct iavc_softc *sc;
	int ret = ENXIO;
	int unit = device_get_unit(dev);
	
	if(isa_get_vendorid(dev))	/* no PnP probes here */
		return ENXIO;

	/* check max unit range */
	
	if (unit >= IAVC_MAXUNIT)
	{
		kprintf("iavc%d: too many units\n", unit);
		return(ENXIO);	
	}

	sc = iavc_find_sc(unit);	/* get softc */	
	
	sc->sc_unit = unit;

	if (!(sc->sc_resources.io_base[0] =
		bus_alloc_resource(dev, SYS_RES_IOPORT,
			&sc->sc_resources.io_rid[0],
			0UL, ~0UL, B1_IOLENGTH, RF_ACTIVE)))
	{
		kprintf("iavc%d: can't allocate io region\n", unit);
		return(ENXIO);                                       
	}

	sc->sc_iobase = rman_get_start(sc->sc_resources.io_base[0]);

	switch(sc->sc_iobase)
	{
		case 0x150:
		case 0x250:
		case 0x300:
		case 0x340:
			break;
		default:
			kprintf("iavc%d: ERROR, invalid i/o base addr 0x%x configured!\n", sc->sc_unit, sc->sc_iobase);
			bus_release_resource(dev, SYS_RES_IOPORT,
					sc->sc_resources.io_rid[0],
		                        sc->sc_resources.io_base[0]);
		return(ENXIO);
	}	
	
	sc->sc_io_bt = rman_get_bustag(sc->sc_resources.io_base[0]);
	sc->sc_io_bh = rman_get_bushandle(sc->sc_resources.io_base[0]);

	/* setup characteristics */

	sc->sc_t1 = FALSE;
	sc->sc_dma = FALSE;

	sc->sc_capi.card_type = CARD_TYPEC_AVM_B1_ISA;
	sc->sc_capi.sc_nbch = 2;

	b1_reset(sc);
	DELAY(100);

	ret = b1_detect(sc);

	if(ret)
	{
		kprintf("iavc%d: no card ? b1_detect returns %0x02x\n", sc->sc_unit, ret);
		return(ENXIO);
	}

	DELAY(100);

	b1_reset(sc);
	
	DELAY(100);

	if(bootverbose)
	{
		kprintf("iavc%d: class = 0x%02x, rev = 0x%02x\n", sc->sc_unit,
			iavc_read_port(sc, B1_ANALYSE),
			iavc_read_port(sc, B1_REVISION));
	}

	device_set_desc(dev, "AVM B1 ISA");
	return(0);
}
Esempio n. 30
0
int
smc_attach(device_t dev)
{
	int			type, error;
	uint16_t		val;
	u_char			eaddr[ETHER_ADDR_LEN];
	struct smc_softc	*sc;
	struct ifnet		*ifp;

	sc = device_get_softc(dev);
	error = 0;

	sc->smc_dev = dev;

	ifp = sc->smc_ifp = if_alloc(IFT_ETHER);
	if (ifp == NULL) {
		error = ENOSPC;
		goto done;
	}

	mtx_init(&sc->smc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);

	/* Set up watchdog callout. */
	callout_init_mtx(&sc->smc_watchdog, &sc->smc_mtx, 0);

	type = SYS_RES_IOPORT;
	if (sc->smc_usemem)
		type = SYS_RES_MEMORY;

	sc->smc_reg_rid = 0;
	sc->smc_reg = bus_alloc_resource(dev, type, &sc->smc_reg_rid, 0, ~0,
	    16, RF_ACTIVE);
	if (sc->smc_reg == NULL) {
		error = ENXIO;
		goto done;
	}

	sc->smc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->smc_irq_rid, 0,
	    ~0, 1, RF_ACTIVE | RF_SHAREABLE);
	if (sc->smc_irq == NULL) {
		error = ENXIO;
		goto done;
	}

	SMC_LOCK(sc);
	smc_reset(sc);
	SMC_UNLOCK(sc);

	smc_select_bank(sc, 3);
	val = smc_read_2(sc, REV);
	sc->smc_chip = (val & REV_CHIP_MASK) >> REV_CHIP_SHIFT;
	sc->smc_rev = (val * REV_REV_MASK) >> REV_REV_SHIFT;
	if (bootverbose)
		device_printf(dev, "revision %x\n", sc->smc_rev);

	callout_init_mtx(&sc->smc_mii_tick_ch, &sc->smc_mtx,
	    CALLOUT_RETURNUNLOCKED);
	if (sc->smc_chip >= REV_CHIP_91110FD) {
		(void)mii_attach(dev, &sc->smc_miibus, ifp,
		    smc_mii_ifmedia_upd, smc_mii_ifmedia_sts, BMSR_DEFCAPMASK,
		    MII_PHY_ANY, MII_OFFSET_ANY, 0);
		if (sc->smc_miibus != NULL) {
			sc->smc_mii_tick = smc_mii_tick;
			sc->smc_mii_mediachg = smc_mii_mediachg;
			sc->smc_mii_mediaioctl = smc_mii_mediaioctl;
		}
	}

	smc_select_bank(sc, 1);
	eaddr[0] = smc_read_1(sc, IAR0);
	eaddr[1] = smc_read_1(sc, IAR1);
	eaddr[2] = smc_read_1(sc, IAR2);
	eaddr[3] = smc_read_1(sc, IAR3);
	eaddr[4] = smc_read_1(sc, IAR4);
	eaddr[5] = smc_read_1(sc, IAR5);

	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_init = smc_init;
	ifp->if_ioctl = smc_ioctl;
	ifp->if_start = smc_start;
	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
	IFQ_SET_READY(&ifp->if_snd);

	ifp->if_capabilities = ifp->if_capenable = 0;

#ifdef DEVICE_POLLING
	ifp->if_capabilities |= IFCAP_POLLING;
#endif

	ether_ifattach(ifp, eaddr);

	/* Set up taskqueue */
	TASK_INIT(&sc->smc_intr, SMC_INTR_PRIORITY, smc_task_intr, ifp);
	TASK_INIT(&sc->smc_rx, SMC_RX_PRIORITY, smc_task_rx, ifp);
	TASK_INIT(&sc->smc_tx, SMC_TX_PRIORITY, smc_task_tx, ifp);
	sc->smc_tq = taskqueue_create_fast("smc_taskq", M_NOWAIT,
	    taskqueue_thread_enqueue, &sc->smc_tq);
	taskqueue_start_threads(&sc->smc_tq, 1, PI_NET, "%s taskq",
	    device_get_nameunit(sc->smc_dev));

	/* Mask all interrupts. */
	sc->smc_mask = 0;
	smc_write_1(sc, MSK, 0);

	/* Wire up interrupt */
	error = bus_setup_intr(dev, sc->smc_irq,
	    INTR_TYPE_NET|INTR_MPSAFE, smc_intr, NULL, sc, &sc->smc_ih);
	if (error != 0)
		goto done;

done:
	if (error != 0)
		smc_detach(dev);
	return (error);
}