예제 #1
0
/*---------------------------------------------------------------------------*
 *	PCI attach
 *---------------------------------------------------------------------------*/
static void
iwic_pci_attach(device_t  parent, device_t  dev, void *aux)
{
	struct iwic_softc *sc = device_private(dev);
	struct iwic_bchan *bchan;
	pci_intr_handle_t ih;
	const char *intrstr;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc_dev = dev;
	sc->sc_cardname = iwic_find_card(pa);

	if (!sc->sc_cardname)
		return;		/* Huh? */

	printf(": %s\n", sc->sc_cardname);

	if (pci_mapreg_map(pa, IWIC_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0,
	    &sc->sc_io_bt, &sc->sc_io_bh, &sc->sc_iobase, &sc->sc_iosize)) {
		aprint_error_dev(sc->sc_dev, "unable to map registers\n");
		return;
	}
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, iwic_pci_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	sc->sc_pc = pc;
	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);

	/* disable interrupts */
	IWIC_WRITE(sc, IWIC_IMASK, 0xff);
	IWIC_READ(sc, ISTA);

	iwic_dchan_init(sc);

	bchan = &sc->sc_bchan[IWIC_BCH_A];
	bchan->offset = B1_CHAN_OFFSET;
	bchan->channel = IWIC_BCH_A;
	bchan->state = ST_IDLE;

	iwic_bchannel_setup(sc, IWIC_BCH_A, BPROT_NONE, 0);

	bchan = &sc->sc_bchan[IWIC_BCH_B];
	bchan->offset = B2_CHAN_OFFSET;
	bchan->channel = IWIC_BCH_B;
	bchan->state = ST_IDLE;

	iwic_bchannel_setup(sc, IWIC_BCH_B, BPROT_NONE, 0);

	iwic_init_linktab(sc);

	iwic_attach_bri(sc);
}
예제 #2
0
파일: i4b_iwic_pci.c 프로젝트: MarginC/kame
/*---------------------------------------------------------------------------*
 *	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);
}