예제 #1
0
void
ohci_pci_attach_deferred(struct device *self)
{
	struct ohci_pci_softc *sc = (struct ohci_pci_softc *)self;
	usbd_status r;
	int s;

	s = splusb();

	sc->sc.sc_dying = 0;
	
	r = ohci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		printf("%s: init failed, error=%d\n",
		    sc->sc.sc_bus.bdev.dv_xname, r);
		bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
		splx(s);
		return;
	}

	sc->sc.sc_powerhook = powerhook_establish(ohci_power, &sc->sc);
	if (sc->sc.sc_powerhook == NULL)
		printf("%s: unable to establish powerhook\n",
		    sc->sc.sc_bus.bdev.dv_xname);

	splx(s);

	/* Attach usb device. */
	sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
				       usbctlprint);
}
예제 #2
0
void
lcd_attach(struct device *parent, struct device *self, void *aux)
{
    struct pxa2x0_lcd_softc *sc = (struct pxa2x0_lcd_softc *)self;
    struct wsemuldisplaydev_attach_args aa;
    extern int glass_console;

    printf("\n");

    pxa2x0_lcd_attach_sub(sc, aux, &lcd_bpp16_screen, CURRENT_DISPLAY,
                          glass_console);

    aa.console = glass_console;
    aa.scrdata = &lcd_screen_list;
    aa.accessops = &lcd_accessops;
    aa.accesscookie = sc;
    aa.defaultscreens = 0;

    (void)config_found(self, &aa, wsemuldisplaydevprint);

    /* Start with approximately 40% of full brightness. */
    lcd_set_brightness(3);

    (void)powerhook_establish(lcd_power, sc);
}
예제 #3
0
void
pxauart_attach(struct device *parent, struct device *self, void *aux)
{
	struct com_softc *sc = (struct com_softc *)self;
	struct pxaip_attach_args *pxa = aux;

	sc->sc_iot = &pxa2x0_a4x_bs_tag;	/* XXX: This sucks */
	sc->sc_iobase = pxa->pxa_addr;
	sc->sc_frequency = PXA2X0_COM_FREQ;
	sc->sc_uarttype = COM_UART_PXA2X0;

#if 0
	if (com_is_console(sc->sc_iot, sc->sc_iobase, &sc->sc_ioh) == 0 &&
	    bus_space_map(sc->sc_iot, sc->sc_iobase, pxa->pxa_size, 0,
			  &sc->sc_ioh)) {
		printf(": can't map registers\n");
		return;
	}
#endif
	bus_space_map(sc->sc_iot, sc->sc_iobase, pxa->pxa_size, 0, &sc->sc_ioh);

	com_attach_subr(sc);

	(void)pxa2x0_intr_establish(pxa->pxa_intr, IPL_TTY, comintr,
	    sc, sc->sc_dev.dv_xname);

	(void)powerhook_establish(&pxauart_power, sc);
}
예제 #4
0
파일: tpm.c 프로젝트: ele7enxxh/dtrace-pf
void
tpm_attach(struct device *parent, struct device *self, void *aux)
{
	struct tpm_softc *sc = (struct tpm_softc *)self;
	struct isa_attach_args *ia = aux;
	bus_addr_t iobase;
	bus_size_t size;
	int rv;

	if (tpm_legacy_probe(ia->ia_iot, ia->ia_iobase)) {
		sc->sc_bt = ia->ia_iot;
		iobase = ia->ia_iobase;
		size = ia->ia_iosize;
		sc->sc_batm = ia->ia_iot;
		sc->sc_init = tpm_legacy_init;
		sc->sc_start = tpm_legacy_start;
		sc->sc_read = tpm_legacy_read;
		sc->sc_write = tpm_legacy_write;
		sc->sc_end = tpm_legacy_end;
	} else {
		sc->sc_bt = ia->ia_memt;
		iobase = ia->ia_maddr;
		size = TPM_SIZE;
		sc->sc_init = tpm_tis12_init;
		sc->sc_start = tpm_tis12_start;
		sc->sc_read = tpm_tis12_read;
		sc->sc_write = tpm_tis12_write;
		sc->sc_end = tpm_tis12_end;
	}

	if (bus_space_map(sc->sc_bt, iobase, size, 0, &sc->sc_bh)) {
		printf(": cannot map registers\n");
		return;
	}

	if ((rv = (sc->sc_init)(sc, ia->ia_irq, sc->sc_dev.dv_xname))) {
		bus_space_unmap(sc->sc_bt, sc->sc_bh, size);
		return;
	}

	/*
	 * Only setup interrupt handler when we have a vector and the
	 * chip is TIS 1.2 compliant.
	 */
	if (sc->sc_init == tpm_tis12_init && ia->ia_irq != IRQUNK &&
	    (sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
	    IPL_TTY, tpm_intr, sc, sc->sc_dev.dv_xname)) == NULL) {
		bus_space_unmap(sc->sc_bt, sc->sc_bh, TPM_SIZE);
		printf("%s: cannot establish interrupt\n",
		    sc->sc_dev.dv_xname);
		return;
	}

#ifdef __FreeBSD__
	sc->sc_suspend = 0;
#else
	sc->sc_suspend = PWR_RESUME;
	sc->sc_powerhook = powerhook_establish(tpm_powerhook, sc);
#endif
}
예제 #5
0
파일: hpcfb.c 프로젝트: MarginC/kame
void
hpcfbattach(struct device *parent, struct device *self, void *aux)
{
	struct hpcfb_softc *sc = (struct hpcfb_softc *)self;
	struct hpcfb_attach_args *ha = aux;
	struct wsemuldisplaydev_attach_args wa;

	sc->sc_accessops = ha->ha_accessops;
	sc->sc_accessctx = ha->ha_accessctx;
	sc->sc_nfbconf = ha->ha_nfbconf;
	sc->sc_fbconflist = ha->ha_fbconflist;

	if (hpcfbconsole) {
		sc->sc_dc = &hpcfb_console_dc;
		hpcfb_console_dc.dc_sc = sc;
		printf(": %dx%d pixels, %d colors, %dx%d chars",
		    sc->sc_dc->dc_rinfo.ri_width,sc->sc_dc->dc_rinfo.ri_height,
		    pow(2, sc->sc_dc->dc_rinfo.ri_depth),
		    sc->sc_dc->dc_rinfo.ri_cols,sc->sc_dc->dc_rinfo.ri_rows);
		/* Set video chip dependent CLUT if any. */
		if (sc->sc_accessops->setclut)
			sc->sc_accessops->setclut(sc->sc_accessctx, 
			    &hpcfb_console_dc.dc_rinfo);
	}
	printf("\n");

	sc->sc_polling = 0; /* XXX */
	sc->sc_mapping = 0; /* XXX */
	callout_init(&sc->sc_switch_callout);

	/* Add a power hook to power management */
	sc->sc_powerhook = powerhook_establish(hpcfb_power, sc);
	if (sc->sc_powerhook == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
		    sc->sc_dev.dv_xname);

	wa.console = hpcfbconsole;
	wa.scrdata = &hpcfb_screenlist;
	wa.accessops = &hpcfb_accessops;
	wa.accesscookie = sc;

	sc->sc_wsdisplay = config_found(self, &wa, wsemuldisplaydevprint);

#ifdef HPCFB_JUMP
	/*
	 * Create a kernel thread to scroll,
	 */
	kthread_create(hpcfb_create_thread, sc);
#endif /* HPCFB_JUMP */
}
예제 #6
0
파일: bivideo.c 프로젝트: MarginC/kame
void
bivideoattach(struct device *parent, struct device *self, void *aux)
{
	struct bivideo_softc *sc = (struct bivideo_softc *)self;
	struct hpcfb_attach_args ha;

	if (attach_flag) {
		panic("%s(%d): bivideo attached twice", __FILE__, __LINE__);
	}
	attach_flag = 1;

	printf(": ");
	if (bivideo_init(&sc->sc_fbconf) != 0) {
		/* just return so that hpcfb will not be attached */
		return;
	}

	printf("pseudo video controller");
	if (console_flag) {
		printf(", console");
	}
	printf("\n");
	printf("%s: framebuffer address: 0x%08lx\n", 
		sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);

	/* Add a suspend hook to power saving */
	sc->sc_powerstate = 0;
	sc->sc_powerhook = powerhook_establish(bivideo_power, sc);
	if (sc->sc_powerhook == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
			sc->sc_dev.dv_xname);

	/* initialize backlight brightness and lcd contrast */
	sc->sc_lcd_inited = 0;
	bivideo_init_brightness(sc, 1);
	bivideo_init_contrast(sc, 1);
	bivideo_init_backlight(sc, 1);

	ha.ha_console = console_flag;
	ha.ha_accessops = &bivideo_ha;
	ha.ha_accessctx = sc;
	ha.ha_curfbconf = 0;
	ha.ha_nfbconf = 1;
	ha.ha_fbconflist = &sc->sc_fbconf;
	ha.ha_curdspconf = 0;
	ha.ha_ndspconf = 1;
	ha.ha_dspconflist = &sc->sc_dspconf;

	config_found(self, &ha, hpcfbprint);
}
예제 #7
0
/*
 * The routine called by the low level scsi routine when it discovers
 * A device suitable for this driver
 */
void
cdattach(struct device *parent, struct device *self, void *aux)
{
	struct scsi_attach_args *sa = aux;
	struct scsi_link *sc_link = sa->sa_sc_link;
	struct cd_softc *cd = (struct cd_softc *)self;

	SC_DEBUG(sc_link, SDEV_DB2, ("cdattach:\n"));

	/*
	 * Store information needed to contact our base driver
	 */
	cd->sc_link = sc_link;
	sc_link->device = &cd_switch;
	sc_link->device_softc = cd;
	if (sc_link->openings > CDOUTSTANDING)
		sc_link->openings = CDOUTSTANDING;

	/*
	 * Initialize and attach the disk structure.
	 */
  	cd->sc_dk.dk_driver = &cddkdriver;
	cd->sc_dk.dk_name = cd->sc_dev.dv_xname;
	disk_attach(&cd->sc_dk);

	/*
	 * Note if this device is ancient.  This is used in cdminphys().
	 */
	if (!(sc_link->flags & SDEV_ATAPI) &&
	    SCSISPC(sa->sa_inqbuf->version) == 0)
		cd->flags |= CDF_ANCIENT;

	printf("\n");

	timeout_set(&cd->sc_timeout, cdrestart, cd);

	if ((cd->sc_cdpwrhook = powerhook_establish(cd_powerhook, cd)) == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
		    cd->sc_dev.dv_xname);
}
예제 #8
0
void
mq200_attach(struct mq200_softc *sc)
{
	unsigned long regval;
	struct hpcfb_attach_args ha;
	int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;

	printf(": ");
	if (mq200_fbinit(&sc->sc_fbconf) != 0) {
		/* just return so that hpcfb will not be attached */
		return;
	}

	sc->sc_fbconf.hf_baseaddr = (u_long)bootinfo->fb_addr;
	sc->sc_fbconf.hf_offset	= (u_long)sc->sc_fbconf.hf_baseaddr -
	    MIPS_PHYS_TO_KSEG1(mips_ptob(mips_btop(sc->sc_baseaddr)));
	DPRINTF("hf_baseaddr=%lx\n", sc->sc_fbconf.hf_baseaddr);
	DPRINTF("hf_offset=%lx\n", sc->sc_fbconf.hf_offset);

	regval = mq200_read(sc, MQ200_PC08R);
	printf("MQ200 Rev.%02lx video controller", regval & 0xff);
	if (console) {
		printf(", console");
	}
	printf("\n");
        printf("%s: framebuffer address: 0x%08lx\n",
	    device_xname(sc->sc_dev), (u_long)bootinfo->fb_addr);

	/*
	 * setup registers
	 */
	sc->sc_flags = 0;
	sc->sc_baseclock = 12288;	/* 12.288 MHz */
#ifdef MQ200_DEBUG
	if (bootverbose) {
		/* dump current setting	*/
		mq200_dump_all(sc);
		mq200_dump_pll(sc);
	}
#endif
	mq200_setup_regctx(sc);
	mq200_mdsetup(sc);
	if (sc->sc_md) {
		int mode;

		switch (sc->sc_fbconf.hf_pixel_width) {
		case  1:	mode = MQ200_GCC_1BPP;		break;
		case  2:	mode = MQ200_GCC_2BPP;		break;
		case  4:	mode = MQ200_GCC_4BPP;		break;
		case  8:	mode = MQ200_GCC_8BPP;		break;
		case 16:	mode = MQ200_GCC_16BPP_DIRECT;	break;
		default:
			printf("%s: %dbpp isn't supported\n",
			    device_xname(sc->sc_dev), sc->sc_fbconf.hf_pixel_width);
			return;
		}

		if (sc->sc_md->md_flags & MQ200_MD_HAVEFP) {
			sc->sc_flags |= MQ200_SC_GC2_ENABLE;	/* FP	*/
		}
#if MQ200_USECRT
		if (sc->sc_md->md_flags & MQ200_MD_HAVECRT) {
			int i;
			sc->sc_flags |= MQ200_SC_GC1_ENABLE;	/* CRT	*/
			for (i = 0; i < mq200_crt_nparams; i++) {
				sc->sc_crt = &mq200_crt_params[i];
				if (sc->sc_md->md_fp_width <=
				    mq200_crt_params[i].width &&
				    sc->sc_md->md_fp_height <=
				    mq200_crt_params[i].height)
					break;
			}
		}
#endif
		mq200_setup(sc);

		if (sc->sc_flags & MQ200_SC_GC2_ENABLE)	/* FP	*/
			mq200_win_enable(sc, MQ200_GC2, mode,
			    sc->sc_fbconf.hf_baseaddr,
			    sc->sc_fbconf.hf_width, sc->sc_fbconf.hf_height,
			    sc->sc_fbconf.hf_bytes_per_plane);
		if (sc->sc_flags & MQ200_SC_GC1_ENABLE)	/* CRT	*/
			mq200_win_enable(sc, MQ200_GC1, mode,
			    sc->sc_fbconf.hf_baseaddr,
			    sc->sc_fbconf.hf_width, sc->sc_fbconf.hf_height,
			    sc->sc_fbconf.hf_bytes_per_plane);
	}
#ifdef MQ200_DEBUG
	if (sc->sc_md == NULL || bootverbose) {
		mq200_dump_pll(sc);
	}
#endif

	/* Add a power hook to power saving */
	sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
	sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev),
	    mq200_power, sc);
	if (sc->sc_powerhook == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
		    device_xname(sc->sc_dev));

	/* Add a hard power hook to power saving */
	sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
	    CONFIG_HOOK_PMEVENT_HARDPOWER,
	    CONFIG_HOOK_SHARE,
	    mq200_hardpower, sc);
	if (sc->sc_hardpowerhook == NULL)
		printf("%s: WARNING: unable to establish hard power hook\n",
		    device_xname(sc->sc_dev));

	/* initialize backlight brightness and lcd contrast */
	sc->sc_lcd_inited = 0;
	mq200_init_brightness(sc, 1);
	mq200_init_contrast(sc, 1);
	mq200_init_backlight(sc, 1);

	if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
		panic("mq200_attach: can't init fb console");
	}

	ha.ha_console = console;
	ha.ha_accessops = &mq200_ha;
	ha.ha_accessctx = sc;
	ha.ha_curfbconf = 0;
	ha.ha_nfbconf = 1;
	ha.ha_fbconflist = &sc->sc_fbconf;
	ha.ha_curdspconf = 0;
	ha.ha_ndspconf = 1;
	ha.ha_dspconflist = &sc->sc_dspconf;

	config_found(sc->sc_dev, &ha, hpcfbprint);

#if NBIVIDEO > 0
	/*
	 * bivideo is no longer need
	 */
	bivideo_dont_attach = 1;
#endif /* NBIVIDEO > 0 */
}
예제 #9
0
/*
 * finishing attaching the socket.  Interrupts may now be on
 * if so expects the pcic interrupt to be blocked
 */
void
pcic_attach_socket_finish(struct pcic_handle *h)
{
	struct pcic_softc *sc = device_private(h->ph_parent);
	int reg;
	char cs[4];

	DPRINTF(("%s: attach finish socket %ld\n", device_xname(h->ph_parent),
	    (long) (h - &sc->handle[0])));

	/*
	 * Set up a powerhook to ensure it continues to interrupt on
	 * card detect even after suspend.
	 * (this works around a bug seen in suspend-to-disk on the
	 * Sony VAIO Z505; on resume, the CSC_INTR state is not preserved).
	 */
	powerhook_establish(device_xname(h->ph_parent), pcic_power, h);

	/* enable interrupts on card detect, poll for them if no irq avail */
	reg = PCIC_CSC_INTR_CD_ENABLE;
	if (sc->irq == -1) {
		if (sc->poll_established == 0) {
			callout_init(&sc->poll_ch, 0);
			callout_reset(&sc->poll_ch, hz / 2, pcic_poll_intr, sc);
			sc->poll_established = 1;
		}
	} else
		reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT;
	pcic_write(h, PCIC_CSC_INTR, reg);

	/* steer above mgmt interrupt to configured place */
	if (sc->irq == 0)
		pcic_write(h, PCIC_INTR, PCIC_INTR_ENABLE);

	/* clear possible card detect interrupt */
	(void) pcic_read(h, PCIC_CSC);

	DPRINTF(("%s: attach finish vendor 0x%02x\n",
	    device_xname(h->ph_parent), h->vendor));

	/* unsleep the cirrus controller */
	if (h->vendor == PCIC_VENDOR_CIRRUS_PD67XX) {
		reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
		if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
			DPRINTF(("%s: socket %02x was suspended\n",
			    device_xname(h->ph_parent), h->sock));
			reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
			pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
		}
	}

	/* if there's a card there, then attach it. */
	reg = pcic_read(h, PCIC_IF_STATUS);
	if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
	    PCIC_IF_STATUS_CARDDETECT_PRESENT) {
		pcic_queue_event(h, PCIC_EVENT_INSERTION);
		h->laststate = PCIC_LASTSTATE_PRESENT;
	} else {
		h->laststate = PCIC_LASTSTATE_EMPTY;
	}

	/*
	 * queue creation of a kernel thread to handle insert/removal events.
	 */
#ifdef DIAGNOSTIC
	if (h->event_thread != NULL)
		panic("pcic_attach_socket: event thread");
#endif
	config_pending_incr(sc->dev);
	snprintf(cs, sizeof(cs), "%d,%d", h->chip, h->socket);

	if (kthread_create(PRI_NONE, 0, NULL, pcic_event_thread, h,
	    &h->event_thread, "%s,%s", device_xname(h->ph_parent), cs)) {
		aprint_error_dev(h->ph_parent,
		    "unable to create event thread for sock 0x%02x\n", h->sock);
		panic("pcic_attach_socket");
	}
}
예제 #10
0
void
nfe_attach(struct device *parent, struct device *self, void *aux)
{
	struct nfe_softc *sc = (struct nfe_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr;
	struct ifnet *ifp;
	bus_size_t memsize;
	pcireg_t memtype;

	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA);
	switch (memtype) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt,
		    &sc->sc_memh, NULL, &memsize, 0) == 0)
			break;
		/* FALLTHROUGH */
	default:
		printf(": could not map mem space\n");
		return;
	}

	if (pci_intr_map(pa, &ih) != 0) {
		printf(": could not map interrupt\n");
		return;
	}

	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nfe_intr, sc,
	    sc->sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(": could not establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}
	printf(": %s", intrstr);

	sc->sc_dmat = pa->pa_dmat;

	nfe_get_macaddr(sc, sc->sc_arpcom.ac_enaddr);
	printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));

	sc->sc_flags = 0;

	switch (PCI_PRODUCT(pa->pa_id)) {
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN2:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN3:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN4:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN5:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_HW_CSUM;
		break;
	case PCI_PRODUCT_NVIDIA_MCP51_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP51_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN4:
		sc->sc_flags |= NFE_40BIT_ADDR;
		break;
	case PCI_PRODUCT_NVIDIA_CK804_LAN1:
	case PCI_PRODUCT_NVIDIA_CK804_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP04_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP04_LAN2:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM;
		break;
	case PCI_PRODUCT_NVIDIA_MCP65_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN4:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR;
		break;
	case PCI_PRODUCT_NVIDIA_MCP55_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP55_LAN2:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_HW_VLAN;
		break;
	}

	/* enable jumbo frames for adapters that support it */
	if (sc->sc_flags & NFE_JUMBO_SUP)
		sc->sc_flags |= NFE_USE_JUMBO;

	/*
	 * Allocate Tx and Rx rings.
	 */
	if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) {
		printf("%s: could not allocate Tx ring\n",
		    sc->sc_dev.dv_xname);
		return;
	}

	if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) {
		printf("%s: could not allocate Rx ring\n",
		    sc->sc_dev.dv_xname);
		nfe_free_tx_ring(sc, &sc->txq);
		return;
	}

	ifp = &sc->sc_arpcom.ac_if;
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = nfe_ioctl;
	ifp->if_start = nfe_start;
	ifp->if_watchdog = nfe_watchdog;
	ifp->if_init = nfe_init;
	ifp->if_baudrate = IF_Gbps(1);
	IFQ_SET_MAXLEN(&ifp->if_snd, NFE_IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);
	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);

	ifp->if_capabilities = IFCAP_VLAN_MTU;

	if (sc->sc_flags & NFE_USE_JUMBO)
		ifp->if_hardmtu = NFE_JUMBO_MTU;

#if NVLAN > 0
	if (sc->sc_flags & NFE_HW_VLAN)
		ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
#endif
	if (sc->sc_flags & NFE_HW_CSUM) {
		ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 |
		    IFCAP_CSUM_UDPv4;
	}

	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = nfe_miibus_readreg;
	sc->sc_mii.mii_writereg = nfe_miibus_writereg;
	sc->sc_mii.mii_statchg = nfe_miibus_statchg;

	ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd,
	    nfe_ifmedia_sts);
	mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);
	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL,
		    0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);

	if_attach(ifp);
	ether_ifattach(ifp);

	timeout_set(&sc->sc_tick_ch, nfe_tick, sc);

	sc->sc_powerhook = powerhook_establish(nfe_power, sc);
}
예제 #11
0
void
aps_attach(struct device *parent, struct device *self, void *aux)
{
	struct aps_softc *sc = (void *)self;
	int iobase, i;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	struct isa_attach_args *ia = aux;

	iobase = ia->ipa_io[0].base;
	iot = sc->aps_iot = ia->ia_iot;

	if (bus_space_map(iot, iobase, APS_ADDR_SIZE, 0, &sc->aps_ioh)) {
		printf(": can't map i/o space\n");
		return;
	}

	ioh = sc->aps_ioh;

	printf("\n");

	if (aps_init(iot, ioh))
		goto out;

	sc->sensors[APS_SENSOR_XACCEL].type = SENSOR_INTEGER;
	snprintf(sc->sensors[APS_SENSOR_XACCEL].desc,
	    sizeof(sc->sensors[APS_SENSOR_XACCEL].desc), "X_ACCEL");

	sc->sensors[APS_SENSOR_YACCEL].type = SENSOR_INTEGER;
	snprintf(sc->sensors[APS_SENSOR_YACCEL].desc,
	    sizeof(sc->sensors[APS_SENSOR_YACCEL].desc), "Y_ACCEL");

	sc->sensors[APS_SENSOR_TEMP1].type = SENSOR_TEMP;
	sc->sensors[APS_SENSOR_TEMP2].type = SENSOR_TEMP;

	sc->sensors[APS_SENSOR_XVAR].type = SENSOR_INTEGER;
	snprintf(sc->sensors[APS_SENSOR_XVAR].desc,
	    sizeof(sc->sensors[APS_SENSOR_XVAR].desc), "X_VAR");

	sc->sensors[APS_SENSOR_YVAR].type = SENSOR_INTEGER;
	snprintf(sc->sensors[APS_SENSOR_YVAR].desc,
	    sizeof(sc->sensors[APS_SENSOR_YVAR].desc), "Y_VAR");

	sc->sensors[APS_SENSOR_KBACT].type = SENSOR_INDICATOR;
	snprintf(sc->sensors[APS_SENSOR_KBACT].desc,
	    sizeof(sc->sensors[APS_SENSOR_KBACT].desc), "Keyboard Active");

	sc->sensors[APS_SENSOR_MSACT].type = SENSOR_INDICATOR;
	snprintf(sc->sensors[APS_SENSOR_MSACT].desc,
	    sizeof(sc->sensors[APS_SENSOR_MSACT].desc), "Mouse Active");

	sc->sensors[APS_SENSOR_LIDOPEN].type = SENSOR_INDICATOR;
	snprintf(sc->sensors[APS_SENSOR_LIDOPEN].desc,
	    sizeof(sc->sensors[APS_SENSOR_LIDOPEN].desc), "Lid Open");

	/* stop hiding and report to the authorities */
	strlcpy(sc->sensordev.xname, sc->sc_dev.dv_xname,
	    sizeof(sc->sensordev.xname));
	for (i = 0; i < APS_NUM_SENSORS ; i++) {
		sensor_attach(&sc->sensordev, &sc->sensors[i]);
	}
	sensordev_install(&sc->sensordev);

	powerhook_establish(aps_power, (void *)sc);

	/* Refresh sensor data every 0.5 seconds */
	timeout_set(&aps_timeout, aps_refresh, sc);
	timeout_add(&aps_timeout, (5 * hz) / 10);
	return;
out:
	printf("%s: failed to initialize\n", sc->sc_dev.dv_xname);
	return;
}
예제 #12
0
static void
obioohci_attach(struct device *parent, struct device *self, void *aux)
{
	struct obioohci_softc *sc = (struct obioohci_softc *)self;
	struct obio_attach_args *obio = aux;
	usbd_status r;

	sc->sc.sc_size = 0;
	sc->sc_ih = NULL;
	sc->sc.sc_bus.dmatag = 0;

	/* Map I/O space */
	if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0,
	    &sc->sc.ioh)) {
		aprint_error(": couldn't map memory space\n");
		return;
	}
	sc->sc.iot = obio->obio_iot;
	sc->sc_addr = obio->obio_addr;
	sc->sc.sc_size = obio->obio_size;
	sc->sc.sc_bus.dmatag = obio->obio_dmac;

	/* XXX copied from ohci_pci.c. needed? */
	bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);

	/* start the usb clock */
#ifdef NOTYET
	pxa2x0_clkman_config(CKEN_USBHC, 1);
#endif
	obioohci_enable(sc);

	/* Disable interrupts, so we don't get any spurious ones. */
	bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
	    OHCI_MIE);

#ifdef NOTYET
	sc->sc_ih = obio_intr_establish(obio->obio_intr, IPL_USB,
		sc->sc.sc_bus.bdev.dv_xname, ohci_intr, &sc->sc);
	if (sc->sc_ih == NULL) {
		aprint_error(": unable to establish interrupt\n");
		goto free_map;
	}
#else
	sc->sc_ih = obioohci_fake_intr_establish(ohci_intr, &sc->sc);
#endif

	strlcpy(sc->sc.sc_vendor, "OMAP2", sizeof(sc->sc.sc_vendor));
	r = ohci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		aprint_error("%s: init failed, error=%d\n",
		    sc->sc.sc_bus.bdev.dv_xname, r);
		goto free_intr;
	}

	sc->sc.sc_powerhook = powerhook_establish(sc->sc.sc_bus.bdev.dv_xname,
	    obioohci_power, sc);
	if (sc->sc.sc_powerhook == NULL) {
		aprint_error("%s: cannot establish powerhook\n",
		    sc->sc.sc_bus.bdev.dv_xname);
	}

	sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus, usbctlprint);

	return;

free_intr:
#ifdef NOTYET
	obio_gpio_intr_disestablish(sc->sc_ih);
#endif
	sc->sc_ih = NULL;
#ifdef NOTYET
free_map:
#endif
	obioohci_disable(sc);
#ifdef NOTYET
	pxa2x0_clkman_config(CKEN_USBHC, 0);
#endif
	bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
	sc->sc.sc_size = 0;
}
예제 #13
0
static void
sed1356_attach(struct device *parent, struct device *self, void *aux)
{
	struct sed1356_softc *sc = (struct sed1356_softc *)self;
	struct hpcfb_attach_args ha;
	int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;

	if (attach_flag) {
		panic("%s(%d): sed1356 attached twice", __FILE__, __LINE__);
	}
	attach_flag = 1;

	if (sed1356_init(&sc->sc_fbconf) != 0) {
		/* just return so that hpcfb will not be attached */
		return;
	}
	printf("\n");

	sc->sc_iot = &sa11x0_bs_tag;
	sc->sc_parent = (struct sa11x0_softc *)parent;
	if (bus_space_map(sc->sc_iot, (bus_addr_t)bootinfo->fb_addr & ~0x3fffff,
	    0x200, 0, &sc->sc_regh)) {
		printf("%s: unable to map register\n", sc->sc_dev.dv_xname);
		return;
	}

	printf("%s: Epson SED1356", sc->sc_dev.dv_xname);
	if (console) {
		printf(", console");
	}
	printf("\n");
	printf("%s: framebuffer address: 0x%08lx\n",
	    sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);

	/* Add a suspend hook to power saving */
	sc->sc_powerstate = 0;
	sc->sc_powerhook = powerhook_establish(self->dv_xname,
	    sed1356_power, sc);
	if (sc->sc_powerhook == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
		    sc->sc_dev.dv_xname);

	/* Initialize backlight brightness and lcd contrast */
	sc->sc_lcd_inited = 0;
	sed1356_init_brightness(sc, 1);
	sed1356_init_contrast(sc, 1);
	sed1356_init_backlight(sc, 1);

	if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0)
		panic("sed1356_attach: cannot init fb console");

	ha.ha_console = console;
	ha.ha_accessops = &sed1356_ha;
	ha.ha_accessctx = sc;
	ha.ha_curfbconf = 0;
	ha.ha_nfbconf = 1;
	ha.ha_fbconflist = &sc->sc_fbconf;
	ha.ha_curdspconf = 0;
	ha.ha_ndspconf = 1;
	ha.ha_dspconflist = &sc->sc_dspconf;

	/* XXX */
	if (platid_match(&platid, &platid_mask_MACH_HP_JORNADA_7XX)) {
		config_hook(CONFIG_HOOK_POWERCONTROL,
			    CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
			    CONFIG_HOOK_SHARE, j720lcd_power, sc);
	}

	config_found(self, &ha, hpcfbprint);
}
예제 #14
0
/*
 * Attach a display.  We need to notice if it is the console, too.
 */
static void
p9100_sbus_attach(struct device *parent, struct device *self, void *args)
{
	struct p9100_softc *sc = device_private(self);
	struct sbus_attach_args *sa = args;
	struct fbdevice *fb = &sc->sc_fb;
	int isconsole;
	int node;
	int i, j;
	uint8_t ver;

#if NWSDISPLAY > 0
	struct wsemuldisplaydev_attach_args aa;
	struct rasops_info *ri;
	unsigned long defattr;
#endif

	sc->sc_last_offset = 0xffffffff;

	/* Remember cookies for p9100_mmap() */
	sc->sc_bustag = sa->sa_bustag;
	sc->sc_ctl_paddr = sbus_bus_addr(sa->sa_bustag,
		sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base);
	sc->sc_ctl_psize = 0x8000;/*(bus_size_t)sa->sa_reg[0].oa_size;*/

	sc->sc_cmd_paddr = sbus_bus_addr(sa->sa_bustag,
		sa->sa_reg[1].oa_space, sa->sa_reg[1].oa_base);
	sc->sc_cmd_psize = (bus_size_t)sa->sa_reg[1].oa_size;

	sc->sc_fb_paddr = sbus_bus_addr(sa->sa_bustag,
		sa->sa_reg[2].oa_space, sa->sa_reg[2].oa_base);
	sc->sc_fb_psize = (bus_size_t)sa->sa_reg[2].oa_size;

	fb->fb_driver = &p9100fbdriver;
	fb->fb_device = &sc->sc_dev;
	fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK;
#ifdef PNOZZ_EMUL_CG3
	fb->fb_type.fb_type = FBTYPE_SUN3COLOR;
#else
	fb->fb_type.fb_type = FBTYPE_P9100;
#endif
	fb->fb_pixels = NULL;

	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;

	node = sa->sa_node;
	isconsole = fb_is_console(node);
	if (!isconsole) {
		aprint_normal("\n");
		aprint_error_dev(self, "fatal error: PROM didn't configure device\n");
		return;
	}

	/*
	 * When the ROM has mapped in a p9100 display, the address
	 * maps only the video RAM, so in any case we have to map the
	 * registers ourselves.  We only need the video RAM if we are
	 * going to print characters via rconsole.
	 */
	if (sbus_bus_map(sc->sc_bustag,
			 sa->sa_reg[0].oa_space,
			 sa->sa_reg[0].oa_base,
			 /*
			  * XXX for some reason the SBus resources don't cover
			  * all registers, so we just map what we need
			  */
			 /*sc->sc_ctl_psize*/ 0x8000,
			 /*BUS_SPACE_MAP_LINEAR*/0, &sc->sc_ctl_memh) != 0) {
		aprint_error_dev(self, "cannot map control registers\n");
		return;
	}

	if (sa->sa_npromvaddrs != 0)
		fb->fb_pixels = (void *)sa->sa_promvaddrs[0];

	if (fb->fb_pixels == NULL) {
		if (sbus_bus_map(sc->sc_bustag,
				sa->sa_reg[2].oa_space,
				sa->sa_reg[2].oa_base,
				sc->sc_fb_psize,
				BUS_SPACE_MAP_LINEAR, &sc->sc_fb_memh) != 0) {
			aprint_error_dev(self, "cannot map framebuffer\n");
			return;
		}
		fb->fb_pixels = (char *)sc->sc_fb_memh;
	} else {
		sc->sc_fb_memh = (bus_space_handle_t) fb->fb_pixels;
	}

	i = p9100_ctl_read_4(sc, 0x0004);
	switch ((i >> 26) & 7) {
	    case 5: fb->fb_type.fb_depth = 32; break;
	    case 7: fb->fb_type.fb_depth = 24; break;
	    case 3: fb->fb_type.fb_depth = 16; break;
	    case 2: fb->fb_type.fb_depth = 8; break;
	    default: {
		panic("pnozz: can't determine screen depth (0x%02x)", i);
	    }
	}
	sc->sc_depth = (fb->fb_type.fb_depth >> 3);

	/* XXX for some reason I get a kernel trap with this */
	sc->sc_width = prom_getpropint(node, "width", 800);
	sc->sc_height = prom_getpropint(node, "height", 600);

	sc->sc_stride = prom_getpropint(node, "linebytes", sc->sc_width *
	    (fb->fb_type.fb_depth >> 3));

	/* check the RAMDAC */
	ver = p9100_ramdac_read_ctl(sc, DAC_VERSION);

	p9100_init_engine(sc);

	fb_setsize_obp(fb, fb->fb_type.fb_depth, sc->sc_width, sc->sc_height,
	    node);

	sbus_establish(&sc->sc_sd, &sc->sc_dev);
	bus_intr_establish(sc->sc_bustag, sa->sa_pri, IPL_BIO,
	    p9100_intr, sc);

	fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
	printf(": rev %d / %x, %dx%d, depth %d mem %x",
	       (i & 7), ver, fb->fb_type.fb_width, fb->fb_type.fb_height,
	       fb->fb_type.fb_depth, (unsigned int)sc->sc_fb_psize);

	fb->fb_type.fb_cmsize = prom_getpropint(node, "cmsize", 256);
	if ((1 << fb->fb_type.fb_depth) != fb->fb_type.fb_cmsize)
		printf(", %d entry colormap", fb->fb_type.fb_cmsize);

	/* Initialize the default color map. */
	/*bt_initcmap(&sc->sc_cmap, 256);*/
	j = 0;
	for (i = 0; i < 256; i++) {
		sc->sc_cmap.cm_map[i][0] = rasops_cmap[j];
		j++;
		sc->sc_cmap.cm_map[i][1] = rasops_cmap[j];
		j++;
		sc->sc_cmap.cm_map[i][2] = rasops_cmap[j];
		j++;
	}
	p9100loadcmap(sc, 0, 256);

	/* make sure we are not blanked */
	if (isconsole)
		p9100_set_video(sc, 1);

	if (shutdownhook_establish(p9100_shutdown, sc) == NULL) {
		panic("%s: could not establish shutdown hook",
		      device_xname(&sc->sc_dev));
	}

	if (isconsole) {
		printf(" (console)\n");
#ifdef RASTERCONSOLE
		/*p9100loadcmap(sc, 255, 1);*/
		fbrcons_init(fb);
#endif
	} else
		printf("\n");

#if NWSDISPLAY > 0
	wsfont_init();

	vcons_init(&sc->vd, sc, &p9100_defscreendesc, &p9100_accessops);
	sc->vd.init_screen = p9100_init_screen;

	vcons_init_screen(&sc->vd, &p9100_console_screen, 1, &defattr);
	p9100_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;

	sc->sc_bg = (defattr >> 16) & 0xff;
	p9100_clearscreen(sc);

	ri = &p9100_console_screen.scr_ri;

	p9100_defscreendesc.nrows = ri->ri_rows;
	p9100_defscreendesc.ncols = ri->ri_cols;
	p9100_defscreendesc.textops = &ri->ri_ops;
	p9100_defscreendesc.capabilities = ri->ri_caps;

	if(isconsole) {
		wsdisplay_cnattach(&p9100_defscreendesc, ri, 0, 0, defattr);
	}

	aa.console = isconsole;
	aa.scrdata = &p9100_screenlist;
	aa.accessops = &p9100_accessops;
	aa.accesscookie = &sc->vd;

	config_found(self, &aa, wsemuldisplaydevprint);
#endif
	/* cursor sprite handling */
	p9100_init_cursor(sc);

	/* attach the fb */
	fb_attach(fb, isconsole);

	/* register with power management */
	sc->sc_video = 1;
	sc->sc_powerstate = PWR_RESUME;
	powerhook_establish(device_xname(&sc->sc_dev), p9100_power_hook, sc);

#if NTCTRL > 0
	/* register callback for external monitor status change */
	tadpole_register_callback(p9100_set_extvga, sc);
#endif
}
예제 #15
0
static void
pxaohci_attach(device_t parent, device_t self, void *aux)
{
	struct pxaohci_softc *sc = device_private(self);
	struct pxaip_attach_args *pxa = aux;

#ifdef USB_DEBUG
	{
		//extern int ohcidebug;
		//ohcidebug = 16;
	}
#endif

	sc->sc.iot = pxa->pxa_iot;
	sc->sc.sc_bus.ub_dmatag = pxa->pxa_dmat;
	sc->sc.sc_size = 0;
	sc->sc_ih = NULL;
	sc->sc.sc_dev = self;
	sc->sc.sc_bus.ub_hcpriv = sc;

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

	/* Map I/O space */
	if (bus_space_map(sc->sc.iot, pxa->pxa_addr, pxa->pxa_size, 0,
	    &sc->sc.ioh)) {
		aprint_error_dev(sc->sc.sc_dev, "couldn't map memory space\n");
		return;
	}
	sc->sc.sc_size = pxa->pxa_size;

	/* XXX copied from ohci_pci.c. needed? */
	bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);

	/* start the usb clock */
	pxa2x0_clkman_config(CKEN_USBHC, 1);
	pxaohci_enable(sc);

	/* Disable interrupts, so we don't get any spurious ones. */
	bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
	    OHCI_MIE);

	sc->sc_ih = pxa2x0_intr_establish(PXA2X0_INT_USBH1, IPL_USB,
	    ohci_intr, &sc->sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(sc->sc.sc_dev,
		    "unable to establish interrupt\n");
		goto free_map;
	}

	strlcpy(sc->sc.sc_vendor, "PXA27x", sizeof(sc->sc.sc_vendor));
	int err = ohci_init(&sc->sc);
	if (err) {
		aprint_error_dev(sc->sc.sc_dev, "init failed, error=%d\n", err);
		goto free_intr;
	}

#if 0
	sc->sc.sc_powerhook = powerhook_establish(device_xname(sc->sc.sc_bus.bdev),
	    pxaohci_power, sc);
	if (sc->sc.sc_powerhook == NULL) {
		aprint_error_dev(sc->sc.sc_dev->sc_bus.bdev, "cannot establish powerhook\n");
	}
#endif

	sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);

	return;

free_intr:
	pxa2x0_intr_disestablish(sc->sc_ih);
	sc->sc_ih = NULL;
free_map:
	pxaohci_disable(sc);
	pxa2x0_clkman_config(CKEN_USBHC, 0);
	bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
	sc->sc.sc_size = 0;
}
예제 #16
0
/*
 * ae_attach:
 *
 *	Attach an ae interface to the system.
 */
void
ae_attach(device_t parent, device_t self, void *aux)
{
	const uint8_t *enaddr;
	prop_data_t ea;
	struct ae_softc *sc = device_private(self);
	struct arbus_attach_args *aa = aux;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	int i, error;

	sc->sc_dev = self;

	callout_init(&sc->sc_tick_callout, 0);

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

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

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

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

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

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

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

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

	if ((error = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct ae_control_data), 1,
	    sizeof(struct ae_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		printf("%s: unable to create control data DMA map, "
		    "error = %d\n", device_xname(sc->sc_dev), error);
		goto fail_3;
	}

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

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

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

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

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

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

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

	sc->sc_tick = ae_mii_tick;

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

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

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

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

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

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

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_6:
	for (i = 0; i < AE_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_rxsoft[i].rxs_dmamap);
	}
 fail_5:
	for (i = 0; i < AE_TXQUEUELEN; i++) {
		if (sc->sc_txsoft[i].txs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_txsoft[i].txs_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
 fail_4:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
 fail_3:
	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
	    sizeof(struct ae_control_data));
 fail_2:
	bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
 fail_1:
	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size);
 fail_0:
	return;
}
예제 #17
0
void
ite8181_attach(struct ite8181_softc *sc)
{
	unsigned long regval;
	struct hpcfb_attach_args ha;
	int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;

	printf(": ");
	if (ite8181_fbinit(&sc->sc_fbconf) != 0) {
		/* just return so that hpcfb will not be attached */
		return;
	}

	regval = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_CLASS);
	printf("ITE8181 Rev.%02lx", regval & ITE8181_REV_MASK);
	if (console) {
		printf(", console");
	}
	printf("\n");
	printf("%s: framebuffer address: 0x%08lx\n",
	    sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
	if (ite8181_lcd_control_disable)
		printf("%s: ite8181 lcd control is DISABLED.\n",
		    sc->sc_dev.dv_xname);

	/* set base offsets */
	sc->sc_mba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_MBA);
	DPRINTFN(1, ("ite8181: Memory base offset %08x\n", sc->sc_mba));
	sc->sc_gba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_GBA);
	DPRINTFN(1, ("ite8181: GUI base offset %08x\n", sc->sc_gba));
	sc->sc_sba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_SBA);
	DPRINTFN(1, ("ite8181: Graphics base offset %08x\n", sc->sc_sba));

	/* assume lcd is on */
	sc->sc_lcd = 1;
	/* erase wince cursor */
	ite8181_erase_cursor(sc);

	/* Add a power hook to power saving */
	sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
	    ite8181_power, sc);
	if (sc->sc_powerhook == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
		    sc->sc_dev.dv_xname);

	/* Add a hard power hook to power saving */
	sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
	    CONFIG_HOOK_PMEVENT_HARDPOWER,
	    CONFIG_HOOK_SHARE,
	    ite8181_hardpower, sc);
	if (sc->sc_hardpowerhook == NULL)
		printf("%s: WARNING: unable to establish hard power hook\n",
		    sc->sc_dev.dv_xname);

	/* initialize backlight brightness and lcd contrast */
	sc->sc_lcd_inited = 0;
	ite8181_init_brightness(sc, 1);
	ite8181_init_contrast(sc, 1);
	ite8181_init_backlight(sc, 1);

	if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
		panic("ite8181_attach: can't init fb console");
	}

	ha.ha_console = console;
	ha.ha_accessops = &ite8181_ha;
	ha.ha_accessctx = sc;
	ha.ha_curfbconf = 0;
	ha.ha_nfbconf = 1;
	ha.ha_fbconflist = &sc->sc_fbconf;
	ha.ha_curdspconf = 0;
	ha.ha_ndspconf = 1;
	ha.ha_dspconflist = &sc->sc_dspconf;

	config_found(&sc->sc_dev, &ha, hpcfbprint);

#if NBIVIDEO > 0
	/*
	 * bivideo is no longer need
	 */
	bivideo_dont_attach = 1;
#endif /* NBIVIDEO > 0 */
}