static void
fms_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa;
	struct fms_softc *sc;
	struct audio_attach_args aa;
	const char *intrstr;
	pci_chipset_tag_t pc;
	pcitag_t pt;
	pci_intr_handle_t ih;
	uint16_t k1;

	pa = aux;
	sc = device_private(self);
	sc->sc_dev = self;
	intrstr = NULL;
	pc = pa->pa_pc;
	pt = pa->pa_tag;
	aprint_naive(": Audio controller\n");
	aprint_normal(": Forte Media FM-801\n");

	if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot,
			   &sc->sc_ioh, &sc->sc_ioaddr, &sc->sc_iosize)) {
		aprint_error_dev(sc->sc_dev, "can't map i/o space\n");
		return;
	}
	if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, 0x30, 2,
				&sc->sc_mpu_ioh))
		panic("fms_attach: can't get mpu subregion handle");
	if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, 0x68, 4,
				&sc->sc_opl_ioh))
		panic("fms_attach: can't get opl subregion handle");

	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih);

	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);

	sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, fms_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");
		mutex_destroy(&sc->sc_lock);
		mutex_destroy(&sc->sc_intr_lock);
		return;
	}

	sc->sc_dmat = pa->pa_dmat;

	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);

	/* Disable legacy audio (SBPro compatibility) */
	pci_conf_write(pc, pt, 0x40, 0);

	/* Reset codec and AC'97 */
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_CODEC_CTL, 0x0020);
	delay(2);		/* > 1us according to AC'97 documentation */
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_CODEC_CTL, 0x0000);
	delay(1);		/* > 168.2ns according to AC'97 documentation */

	/* Set up volume */
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_PCM_VOLUME, 0x0808);
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_FM_VOLUME, 0x0808);
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_I2S_VOLUME, 0x0808);

	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_RECORD_SOURCE, 0x0000);

	/* Unmask playback, record and mpu interrupts, mask the rest */
	k1 = bus_space_read_2(sc->sc_iot, sc->sc_ioh, FM_INTMASK);
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_INTMASK,
	    (k1 & ~(FM_INTMASK_PLAY | FM_INTMASK_REC | FM_INTMASK_MPU)) |
	     FM_INTMASK_VOL);
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_INTSTATUS,
	    FM_INTSTATUS_PLAY | FM_INTSTATUS_REC | FM_INTSTATUS_MPU |
	    FM_INTSTATUS_VOL);

	sc->host_if.arg = sc;
	sc->host_if.attach = fms_attach_codec;
	sc->host_if.read = fms_read_codec;
	sc->host_if.write = fms_write_codec;
	sc->host_if.reset = fms_reset_codec;

	if (ac97_attach(&sc->host_if, self, &sc->sc_lock) != 0) {
		mutex_destroy(&sc->sc_intr_lock);
		mutex_destroy(&sc->sc_lock);
		return;
	}

	audio_attach_mi(&fms_hw_if, sc, sc->sc_dev);

	aa.type = AUDIODEV_TYPE_OPL;
	aa.hwif = NULL;
	aa.hdl = NULL;
	config_found(sc->sc_dev, &aa, audioprint);

	aa.type = AUDIODEV_TYPE_MPU;
	aa.hwif = NULL;
	aa.hdl = NULL;
	sc->sc_mpu_dev = config_found(sc->sc_dev, &aa, audioprint);
}
static void
wzero3kbd_attach(device_t parent, device_t self, void *aux)
{
	struct wzero3kbd_softc *sc = device_private(self);
	struct pxaip_attach_args *pxa = (struct pxaip_attach_args *)aux;
	struct hpckbd_attach_args haa;
	const struct wzero3kbd_model *model;

	sc->sc_dev = self;

	model = wzero3kbd_lookup();
	if (model == NULL) {
		aprint_error(": unknown model\n");
		return;
	}

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

	sc->sc_key_pin = model->key_pin;
	sc->sc_power_pin = model->power_pin;
	sc->sc_reset_pin = model->reset_pin;
	sc->sc_ncolumn = model->ncolumn;
	sc->sc_nrow = model->nrow;

	sc->sc_iot = pxa->pxa_iot;
	if (bus_space_map(sc->sc_iot, PXA2X0_CS2_START, REGMAPSIZE, 0,
	    &sc->sc_ioh)) {
		aprint_error_dev(self, "couldn't map registers.\n");
		return;
	}

	sc->sc_okeystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF,
	    M_NOWAIT | M_ZERO);
	sc->sc_keystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF,
	    M_NOWAIT | M_ZERO);
	if (sc->sc_okeystat == NULL || sc->sc_keystat == NULL) {
		aprint_error_dev(self, "couldn't alloc memory.\n");
		if (sc->sc_okeystat)
			free(sc->sc_okeystat, M_DEVBUF);
		if (sc->sc_keystat)
			free(sc->sc_keystat, M_DEVBUF);
		return;
	}

	sc->sc_if.hii_ctx = sc;
	sc->sc_if.hii_establish = wzero3kbd_input_establish;
	sc->sc_if.hii_poll = wzero3kbd_poll;

	/* Attach console if not using serial. */
	if (!(bootinfo->bi_cnuse & BI_CNUSE_SERIAL))
		hpckbd_cnattach(&sc->sc_if);

	/* Install interrupt handler. */
	if (sc->sc_key_pin >= 0) {
		pxa2x0_gpio_set_function(sc->sc_key_pin, GPIO_IN);
		sc->sc_key_ih = pxa2x0_gpio_intr_establish(sc->sc_key_pin,
		    IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr, sc);
		if (sc->sc_key_ih == NULL) {
			aprint_error_dev(sc->sc_dev,
			    "couldn't establish key interrupt\n");
		}
	} else {
		sc->sc_interval = KEY_INTERVAL / (1000 / hz);
		if (sc->sc_interval < 1)
			sc->sc_interval = 1;
		callout_init(&sc->sc_keyscan_ch, 0);
		callout_reset(&sc->sc_keyscan_ch, sc->sc_interval,
		    wzero3kbd_tick, sc);
	}

	/* power key */
	if (sc->sc_power_pin >= 0) {
		pxa2x0_gpio_set_function(sc->sc_power_pin, GPIO_IN);
		sc->sc_power_ih = pxa2x0_gpio_intr_establish(
		    sc->sc_power_pin, IST_EDGE_BOTH, IPL_TTY,
		    wzero3kbd_power_intr, sc);
		if (sc->sc_power_ih == NULL) {
			aprint_error_dev(sc->sc_dev,
			    "couldn't establish power key interrupt\n");
		}
	}

	/* reset button */
	if (sc->sc_reset_pin >= 0) {
		pxa2x0_gpio_set_function(sc->sc_reset_pin, GPIO_IN);
		sc->sc_reset_ih = pxa2x0_gpio_intr_establish(
		    sc->sc_reset_pin, IST_EDGE_BOTH, IPL_TTY,
		    wzero3kbd_reset_intr, sc);
		if (sc->sc_reset_ih == NULL) {
			aprint_error_dev(sc->sc_dev,
			    "couldn't establish reset key interrupt\n");
		}

		sc->sc_smpsw.smpsw_name = device_xname(self);
		sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_RESET;
		if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) {
			aprint_error_dev(sc->sc_dev,
			    "unable to register reset event handler\n");
		}
	}

	/* Attach hpckbd. */
	haa.haa_ic = &sc->sc_if;
	config_found(self, &haa, hpckbd_print);

#if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) || defined(KEYTEST5)
	sc->sc_test_ih = NULL;
	sc->sc_test_pin = -1;
	sc->sc_nouse_pin = -1;
	sc->sc_nouse_pin2 = -1;
	sc->sc_nouse_pin3 = -1;
	sc->sc_bit = 0x01;
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH)
	 || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) {
		sc->sc_nouse_pin = GPIO_WS003SH_SD_DETECT;  /* SD_DETECT */
		sc->sc_nouse_pin2 = 86;  /* Vsync? */
		sc->sc_nouse_pin3 = 89;  /* RESET? */
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) {
		sc->sc_nouse_pin = GPIO_WS007SH_SD_DETECT;  /* SD_DETECT */
		sc->sc_nouse_pin2 = 77;  /* Vsync? */
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) {
		sc->sc_nouse_pin = GPIO_WS011SH_SD_DETECT;  /* SD_DETECT */
		sc->sc_nouse_pin2 = 77;  /* Vsync? */
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS020SH)) {
		sc->sc_nouse_pin = GPIO_WS020SH_SD_DETECT;  /* SD_DETECT */
		sc->sc_nouse_pin2 = 77;  /* Vsync? */
	}

#ifdef KEYTEST
	for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) {
		if (sc->sc_test_pin != sc->sc_nouse_pin
		 && sc->sc_test_pin != sc->sc_nouse_pin2
		 && sc->sc_test_pin != sc->sc_nouse_pin3
		 && sc->sc_test_pin != sc->sc_key_pin
		 && sc->sc_test_pin != sc->sc_power_pin
		 && sc->sc_test_pin != sc->sc_reset_pin
		 && GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(sc->sc_test_pin)))
			break;
	}
	if (sc->sc_test_pin < PXA270_GPIO_NPINS) {
		printf("GPIO_IN: GPIO pin #%d\n", sc->sc_test_pin);
		sc->sc_test_ih = pxa2x0_gpio_intr_establish(sc->sc_test_pin,
		    IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr2, sc);
	} else {
		sc->sc_test_pin = -1;
	}
#endif

#ifdef KEYTEST3
	{
		int i;
		printf("pin: ");
		for (i = 0; i < PXA270_GPIO_NPINS; i++) {
			if (i == sc->sc_nouse_pin
			 || i == sc->sc_nouse_pin2
			 || i == sc->sc_nouse_pin3
			 || i == sc->sc_key_pin
			 || i == sc->sc_power_pin
			 || i == sc->sc_reset_pin)
				continue;

			printf("%d, ", i);
			if (GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(i))) {
				pxa2x0_gpio_intr_establish(i, IST_EDGE_BOTH,
				    IPL_TTY, wzero3kbd_intr3, (void *)(long)i);
			}
		}
	}
#endif

#ifdef KEYTEST4
	for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) {
		if (sc->sc_test_pin != sc->sc_nouse_pin
		 && sc->sc_test_pin != sc->sc_nouse_pin2
		 && sc->sc_test_pin != sc->sc_nouse_pin3
		 && sc->sc_test_pin != sc->sc_key_pin
		 && sc->sc_test_pin != sc->sc_power_pin
		 && sc->sc_test_pin != sc->sc_reset_pin
		 && GPIO_IS_GPIO_OUT(pxa2x0_gpio_get_function(sc->sc_test_pin)))
			break;
	}
	if (sc->sc_test_pin < PXA270_GPIO_NPINS) {
		printf("GPIO_OUT: GPIO pin #%d\n", sc->sc_test_pin);
	} else {
		sc->sc_test_pin = -1;
	}
#endif
#ifdef KEYTEST5
	sc->sc_test_pin = 0x00;
	sc->sc_bit = 0x01;
#endif
#endif
}
Exemple #3
0
void
hdlg_mainbus_attach(struct device *parent, struct device *self, void *aux)
{
	struct i80321_softc *sc = (void *) self;
	pcireg_t b0u, b0l, b1u, b1l;
	paddr_t memstart;
	psize_t memsize;

	hdlg_mainbus_found = 1;

	/*
	 * Fill in the space tag for the i80321's own devices,
	 * and hand-craft the space handle for it (the device
	 * was mapped during early bootstrap).
	 */
	i80321_bs_init(&i80321_bs_tag, sc);
	sc->sc_st = &i80321_bs_tag;
	sc->sc_sh = HDLG_80321_VBASE;

	/*
	 * Slice off a subregion for the Memory Controller -- we need it
	 * here in order read the memory size.
	 */
	if (bus_space_subregion(sc->sc_st, sc->sc_sh, VERDE_MCU_BASE,
	    VERDE_MCU_SIZE, &sc->sc_mcu_sh))
		panic("%s: unable to subregion MCU registers",
		    device_xname(&sc->sc_dev));

	if (bus_space_subregion(sc->sc_st, sc->sc_sh, VERDE_ATU_BASE,
	    VERDE_ATU_SIZE, &sc->sc_atu_sh))
		panic("%s: unable to subregion ATU registers",
		    device_xname(&sc->sc_dev));

	/*
	 * We have mapped the PCI I/O windows in the early bootstrap phase.
	 */
	sc->sc_iow_vaddr = HDLG_IOW_VBASE;

	/*
	 * Check the configuration of the ATU to see if another BIOS
	 * has configured us.  If a PC BIOS didn't configure us, then:
	 * 	IQ80321: BAR0 00000000.0000000c BAR1 is 00000000.8000000c.
	 * 	IQ31244: BAR0 00000000.00000004 BAR1 is 00000000.0000000c.
	 * If a BIOS has configured us, at least one of those should be
	 * different.  This is pretty fragile, but it's not clear what
	 * would work better.
	 */
	b0l = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START+0x0);
	b0u = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START+0x4);
	b1l = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START+0x8);
	b1u = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START+0xc);
	b0l &= PCI_MAPREG_MEM_ADDR_MASK;
	b0u &= PCI_MAPREG_MEM_ADDR_MASK;
	b1l &= PCI_MAPREG_MEM_ADDR_MASK;
	b1u &= PCI_MAPREG_MEM_ADDR_MASK;

	if ((b0u != b1u) || (b0l != 0) || ((b1l & ~0x80000000U) != 0))
		sc->sc_is_host = 0;
	else
		sc->sc_is_host = 1;

	aprint_naive(": i80219 I/O Processor\n");
	aprint_normal(": i80219 I/O Processor, acting as PCI %s\n",
	    sc->sc_is_host ? "host" : "slave");

	i80321_sdram_bounds(sc->sc_st, sc->sc_mcu_sh, &memstart, &memsize);

	/*
	 * We set up the Inbound Windows as follows:
	 *
	 *	0	Access to i80219 PMMRs
	 *
	 *	1	Reserve space for private devices
	 *
	 *	2	RAM access
	 *
	 *	3	Unused.
	 *
	 * This chunk needs to be customized for each IOP321 application.
	 */
#if 0
	sc->sc_iwin[0].iwin_base_lo = VERDE_PMMR_BASE;
	sc->sc_iwin[0].iwin_base_hi = 0;
	sc->sc_iwin[0].iwin_xlate = VERDE_PMMR_BASE;
	sc->sc_iwin[0].iwin_size = VERDE_PMMR_SIZE;
#endif

	if (sc->sc_is_host) {
		/* Map PCI:Local 1:1. */
		sc->sc_iwin[1].iwin_base_lo = VERDE_OUT_XLATE_MEM_WIN0_BASE |
		    PCI_MAPREG_MEM_PREFETCHABLE_MASK |
		    PCI_MAPREG_MEM_TYPE_64BIT;
		sc->sc_iwin[1].iwin_base_hi = 0;
	} else {
		sc->sc_iwin[1].iwin_base_lo = 0;
		sc->sc_iwin[1].iwin_base_hi = 0;
	}
	sc->sc_iwin[1].iwin_xlate = VERDE_OUT_XLATE_MEM_WIN0_BASE;
	sc->sc_iwin[1].iwin_size = VERDE_OUT_XLATE_MEM_WIN_SIZE;

	if (sc->sc_is_host) {
		sc->sc_iwin[2].iwin_base_lo = memstart |
		    PCI_MAPREG_MEM_PREFETCHABLE_MASK |
		    PCI_MAPREG_MEM_TYPE_64BIT;
		sc->sc_iwin[2].iwin_base_hi = 0;
	} else {
		sc->sc_iwin[2].iwin_base_lo = 0;
		sc->sc_iwin[2].iwin_base_hi = 0;
	}
	sc->sc_iwin[2].iwin_xlate = memstart;
	sc->sc_iwin[2].iwin_size = memsize;

	if (sc->sc_is_host) {
		sc->sc_iwin[3].iwin_base_lo = 0 |
		    PCI_MAPREG_MEM_PREFETCHABLE_MASK |
		    PCI_MAPREG_MEM_TYPE_64BIT;
	} else {
		sc->sc_iwin[3].iwin_base_lo = 0;
	}
	sc->sc_iwin[3].iwin_base_hi = 0;
	sc->sc_iwin[3].iwin_xlate = 0;
	sc->sc_iwin[3].iwin_size = 0;

	/*
	 * We set up the Outbound Windows as follows:
	 *
	 *	0	Access to private PCI space.
	 *
	 *	1	Unused.
	 */
	sc->sc_owin[0].owin_xlate_lo =
	    PCI_MAPREG_MEM_ADDR(sc->sc_iwin[1].iwin_base_lo);
	sc->sc_owin[0].owin_xlate_hi = sc->sc_iwin[1].iwin_base_hi;

	/*
	 * Set the Secondary Outbound I/O window to map
	 * to PCI address 0 for all 64K of the I/O space.
	 */
	sc->sc_ioout_xlate = 0;
	sc->sc_ioout_xlate_offset = 0x1000;

	/*
	 * Initialize the interrupt part of our PCI chipset tag.
	 */
	hdlg_pci_init(&sc->sc_pci_chipset, sc);

	i80321_attach(sc);
}
Exemple #4
0
void 
uftdi_attach(device_t parent, device_t self, void *aux)
{
	struct uftdi_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usbd_interface_handle iface;
	usb_device_descriptor_t *ddesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	const char *devname = device_xname(self);
	int i,idx;
	usbd_status err;
	struct ucom_attach_args uca;

	DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc));

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

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

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1);
	if (err) {
		aprint_error("\n%s: failed to set configuration, err=%s\n",
		       devname, usbd_errstr(err));
		goto bad;
	}

	sc->sc_dev = self;
	sc->sc_udev = dev;
	sc->sc_numports = 1;
	sc->sc_type = UFTDI_TYPE_8U232AM; /* most devices are post-8U232AM */
	sc->sc_hdrlen = 0;
	if (uaa->vendor == USB_VENDOR_FTDI
	    && uaa->product == USB_PRODUCT_FTDI_SERIAL_8U100AX) {
		sc->sc_type = UFTDI_TYPE_SIO;
		sc->sc_hdrlen = 1;
	}

	ddesc = usbd_get_device_descriptor(dev);
	sc->sc_chiptype = UGETW(ddesc->bcdDevice);
	switch (sc->sc_chiptype) {
	case 0x500: /* 2232D */
	case 0x700: /* 2232H */
		sc->sc_numports = 2;
		break;
	case 0x800: /* 4232H */
		sc->sc_numports = 4;
		break;
	case 0x200: /* 232/245AM */
	case 0x400: /* 232/245BL */
	case 0x600: /* 232/245R */
	default:
		break;
	}

	for (idx = UFTDI_IFACE_INDEX; idx < sc->sc_numports; idx++) {
		err = usbd_device2interface_handle(dev, idx, &iface);
		if (err) {
			aprint_error(
			    "\n%s: failed to get interface idx=%d, err=%s\n",
			    devname, idx, usbd_errstr(err));
			goto bad;
		}

		id = usbd_get_interface_descriptor(iface);

		sc->sc_iface[idx] = iface;

		uca.bulkin = uca.bulkout = -1;
		uca.ibufsize = uca.obufsize = 0;
		for (i = 0; i < id->bNumEndpoints; i++) {
			int addr, dir, attr;
			ed = usbd_interface2endpoint_descriptor(iface, i);
			if (ed == NULL) {
				aprint_error_dev(self,
				    "could not read endpoint descriptor: %s\n",
				    usbd_errstr(err));
				goto bad;
			}

			addr = ed->bEndpointAddress;
			dir = UE_GET_DIR(ed->bEndpointAddress);
			attr = ed->bmAttributes & UE_XFERTYPE;
			if (dir == UE_DIR_IN && attr == UE_BULK) {
				uca.bulkin = addr;
				uca.ibufsize = UGETW(ed->wMaxPacketSize);
				if (uca.ibufsize >= UFTDI_MAX_IBUFSIZE)
					uca.ibufsize = UFTDI_MAX_IBUFSIZE;
			} else if (dir == UE_DIR_OUT && attr == UE_BULK) {
				uca.bulkout = addr;
				uca.obufsize = UGETW(ed->wMaxPacketSize)
				    - sc->sc_hdrlen;
				if (uca.obufsize >= UFTDI_MAX_OBUFSIZE)
					uca.obufsize = UFTDI_MAX_OBUFSIZE;
				/* Limit length if we have a 6-bit header.  */
				if ((sc->sc_hdrlen > 0) &&
				    (uca.obufsize > UFTDIOBUFSIZE))
					uca.obufsize = UFTDIOBUFSIZE;
			} else {
				aprint_error_dev(self,
				    "unexpected endpoint\n");
				goto bad;
			}
		}
		if (uca.bulkin == -1) {
			aprint_error_dev(self,
			    "Could not find data bulk in\n");
			goto bad;
		}
		if (uca.bulkout == -1) {
			aprint_error_dev(self,
			    "Could not find data bulk out\n");
			goto bad;
		}

		uca.portno = FTDI_PIT_SIOA + idx;
		/* bulkin, bulkout set above */
		if (uca.ibufsize == 0)
			uca.ibufsize = UFTDIIBUFSIZE;
		uca.ibufsizepad = uca.ibufsize;
		if (uca.obufsize == 0)
			uca.obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen;
		uca.opkthdrlen = sc->sc_hdrlen;
		uca.device = dev;
		uca.iface = iface;
		uca.methods = &uftdi_methods;
		uca.arg = sc;
		uca.info = NULL;

		DPRINTF(("uftdi: in=0x%x out=0x%x isize=0x%x osize=0x%x\n",
			uca.bulkin, uca.bulkout,
			uca.ibufsize, uca.obufsize));
		sc->sc_subdev[idx] = config_found_sm_loc(self, "ucombus", NULL,
		    &uca, ucomprint, ucomsubmatch);
	}

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

	return;

bad:
	DPRINTF(("uftdi_attach: ATTACH ERROR\n"));
	sc->sc_dying = 1;
	return;
}
Exemple #5
0
static void
zkbd_attach(device_t parent, device_t self, void *aux)
{
	struct zkbd_softc *sc = device_private(self);
	struct wskbddev_attach_args a;
	int pin, i;

	sc->sc_dev = self;
	zkbd_sc = sc;

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

	sc->sc_polling = 0;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	sc->sc_rawkbd = 0;
#endif

	callout_init(&sc->sc_roll_to, 0);
	callout_setfunc(&sc->sc_roll_to, zkbd_poll, sc);
#ifdef WSDISPLAY_COMPAT_RAWKBD
	callout_init(&sc->sc_rawrepeat_ch, 0);
	callout_setfunc(&sc->sc_rawrepeat_ch, zkbd_rawrepeat, sc);
#endif

	if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
		sc->sc_sense_array = gpio_sense_pins_c3000;
		sc->sc_strobe_array = gpio_strobe_pins_c3000;
		sc->sc_nsense = __arraycount(gpio_sense_pins_c3000);
		sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c3000);
		sc->sc_stuck_keys = stuck_keys_c3000;
		sc->sc_nstuck = __arraycount(stuck_keys_c3000);
		sc->sc_maxkbdcol = 10;
		sc->sc_onkey_pin = 95;
		sc->sc_sync_pin = 16;
		sc->sc_swa_pin = 97;
		sc->sc_swb_pin = 96;
		sc->sc_keymapdata = &zkbd_keymapdata;
#ifdef WSDISPLAY_COMPAT_RAWKBD
		sc->sc_xt_keymap = xt_keymap;
#endif
	} else if (ZAURUS_ISC860) {
		sc->sc_sense_array = gpio_sense_pins_c860;
		sc->sc_strobe_array = gpio_strobe_pins_c860;
		sc->sc_nsense = __arraycount(gpio_sense_pins_c860);
		sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c860);
		sc->sc_stuck_keys = stuck_keys_c860;
		sc->sc_nstuck = __arraycount(stuck_keys_c860);
		sc->sc_maxkbdcol = 0;
		sc->sc_onkey_pin = -1;
		sc->sc_sync_pin = -1;
		sc->sc_swa_pin = -1;
		sc->sc_swb_pin = -1;
		sc->sc_keymapdata = &zkbd_keymapdata_c860;
#ifdef WSDISPLAY_COMPAT_RAWKBD
		sc->sc_xt_keymap = xt_keymap_c860;
#endif
	} else {
		/* XXX */
		return;
	}

	if (!pmf_device_register(sc->sc_dev, NULL, zkbd_resume))
		aprint_error_dev(sc->sc_dev,
		    "couldn't establish power handler\n");

	sc->sc_okeystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
	    M_DEVBUF, M_NOWAIT);
	memset(sc->sc_okeystate, 0, sc->sc_nsense * sc->sc_nstrobe);

	sc->sc_keystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
	    M_DEVBUF, M_NOWAIT);
	memset(sc->sc_keystate, 0, sc->sc_nsense * sc->sc_nstrobe);

	/* set all the strobe bits */
	for (i = 0; i < sc->sc_nstrobe; i++) {
		pin = sc->sc_strobe_array[i];
		if (pin == -1)
			continue;
		pxa2x0_gpio_set_function(pin, GPIO_SET|GPIO_OUT);
	}

	/* set all the sense bits */
	for (i = 0; i < sc->sc_nsense; i++) {
		pin = sc->sc_sense_array[i];
		if (pin == -1)
			continue;
		pxa2x0_gpio_set_function(pin, GPIO_IN);
		if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
			pxa2x0_gpio_intr_establish(pin, IST_EDGE_BOTH,
			    IPL_TTY, zkbd_irq_c3000, sc);
		} else if (ZAURUS_ISC860) {
			pxa2x0_gpio_intr_establish(pin, IST_EDGE_RISING,
			    IPL_TTY, zkbd_irq_c860, sc);
		}
	}

	if (sc->sc_onkey_pin >= 0)
		pxa2x0_gpio_intr_establish(sc->sc_onkey_pin, IST_EDGE_BOTH,
		    IPL_TTY, zkbd_on, sc);
	if (sc->sc_sync_pin >= 0)
		pxa2x0_gpio_intr_establish(sc->sc_sync_pin, IST_EDGE_RISING,
		    IPL_TTY, zkbd_sync, sc);
	if (sc->sc_swa_pin >= 0)
		pxa2x0_gpio_intr_establish(sc->sc_swa_pin, IST_EDGE_BOTH,
		    IPL_TTY, zkbd_hinge, sc);
	if (sc->sc_swb_pin >= 0)
		pxa2x0_gpio_intr_establish(sc->sc_swb_pin, IST_EDGE_BOTH,
		    IPL_TTY, zkbd_hinge, sc);

	if (glass_console) {
		wskbd_cnattach(&zkbd_consops, sc, sc->sc_keymapdata);
		a.console = 1;
	} else {
		a.console = 0;
	}
	a.keymap = sc->sc_keymapdata;
	a.accessops = &zkbd_accessops;
	a.accesscookie = sc;

	zkbd_hinge(sc);		/* to initialize sc_hinge */

	sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
}
Exemple #6
0
void
wbsio_attach(device_t parent, device_t self, void *aux)
{
	struct wbsio_softc *sc = device_private(self);
	struct isa_attach_args *ia = aux;
	const char *desc = NULL;
	const char *vendor = "Winbond";
	uint8_t reg;

	sc->sc_dev = self;

	sc->sc_ia = *ia;

	/* Map ISA I/O space */
	sc->sc_iot = ia->ia_iot;
	if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr,
	    WBSIO_IOSIZE, 0, &sc->sc_ioh)) {
		aprint_error(": can't map i/o space\n");
		return;
	}

	/* Enter configuration mode */
	wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);

	/* Read device ID */
	reg = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
	switch (reg) {
	case WBSIO_ID_W83627HF:
		desc = "W83627HF";
		break;
	case WBSIO_ID_W83627THF:
		desc = "W83627THF";
		break;
	case WBSIO_ID_W83627EHF:
		desc = "W83627EHF";
		break;
	case WBSIO_ID_W83627DHG:
		desc = "W83627DHG";
		break;
	case WBSIO_ID_W83637HF:
		desc = "W83637HF";
		break;
	case WBSIO_ID_W83667HG:
		desc = "W83667HG";
		break;
	case WBSIO_ID_W83697HF:
		desc = "W83697HF";
		break;
	case WBSIO_ID_NCT6776F:
		vendor = "Nuvoton";
		desc = "NCT6776F";
		break;
	}
	/* Read device revision */
	reg = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);

	aprint_naive("\n");
	aprint_normal(": %s LPC Super I/O %s rev 0x%02x\n", vendor, desc, reg);

	/* Escape from configuration mode */
	wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
	wbsio_rescan(self, "wbsio", NULL);
}
Exemple #7
0
static void
vmt_attach(device_t parent, device_t self, void *aux)
{
	int rv;
	struct vmt_softc *sc = device_private(self);

	aprint_naive("\n");
	aprint_normal(": %s\n", vmt_type());

	sc->sc_dev = self;
	sc->sc_log = NULL;

	callout_init(&sc->sc_tick, 0);
	callout_init(&sc->sc_tclo_tick, 0);
	callout_init(&sc->sc_clock_sync_tick, 0);

	sc->sc_clock_sync_period_seconds = VMT_CLOCK_SYNC_PERIOD_SECONDS;

	rv = vmt_sysctl_setup_root(self);
	if (rv != 0) {
		aprint_error_dev(self, "failed to initialize sysctl "
		    "(err %d)\n", rv);
		goto free;
	}

	sc->sc_rpc_buf = kmem_alloc(VMT_RPC_BUFLEN, KM_SLEEP);
	if (sc->sc_rpc_buf == NULL) {
		aprint_error_dev(self, "unable to allocate buffer for RPC\n");
		goto free;
	}

	if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) {
		aprint_error_dev(self, "failed to open backdoor RPC channel (TCLO protocol)\n");
		goto free;
	}
	sc->sc_tclo_rpc_open = true;

	/* don't know if this is important at all yet */
	if (vm_rpc_send_rpci_tx(sc, "tools.capability.hgfs_server toolbox 1") != 0) {
		aprint_error_dev(self, "failed to set HGFS server capability\n");
		goto free;
	}

	pmf_device_register1(self, NULL, NULL, vmt_shutdown);

	sysmon_task_queue_init();

	sc->sc_ev_power.ev_smpsw.smpsw_type = PSWITCH_TYPE_POWER;
	sc->sc_ev_power.ev_smpsw.smpsw_name = device_xname(self);
	sc->sc_ev_power.ev_code = PSWITCH_EVENT_PRESSED;
	sysmon_pswitch_register(&sc->sc_ev_power.ev_smpsw);
	sc->sc_ev_reset.ev_smpsw.smpsw_type = PSWITCH_TYPE_RESET;
	sc->sc_ev_reset.ev_smpsw.smpsw_name = device_xname(self);
	sc->sc_ev_reset.ev_code = PSWITCH_EVENT_PRESSED;
	sysmon_pswitch_register(&sc->sc_ev_reset.ev_smpsw);
	sc->sc_ev_sleep.ev_smpsw.smpsw_type = PSWITCH_TYPE_SLEEP;
	sc->sc_ev_sleep.ev_smpsw.smpsw_name = device_xname(self);
	sc->sc_ev_sleep.ev_code = PSWITCH_EVENT_RELEASED;
	sysmon_pswitch_register(&sc->sc_ev_sleep.ev_smpsw);
	sc->sc_smpsw_valid = true;

	callout_setfunc(&sc->sc_tick, vmt_tick, sc);
	callout_schedule(&sc->sc_tick, hz);

	callout_setfunc(&sc->sc_tclo_tick, vmt_tclo_tick, sc);
	callout_schedule(&sc->sc_tclo_tick, hz);
	sc->sc_tclo_ping = 1;

	callout_setfunc(&sc->sc_clock_sync_tick, vmt_clock_sync_tick, sc);
	callout_schedule(&sc->sc_clock_sync_tick,
	    mstohz(sc->sc_clock_sync_period_seconds * 1000));

	vmt_sync_guest_clock(sc);

	return;

free:
	if (sc->sc_rpc_buf)
		kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN);
	pmf_device_register(self, NULL, NULL);
	if (sc->sc_log)
		sysctl_teardown(&sc->sc_log);
}
/* Attach */
void
url_attach(device_t parent, device_t self, void *aux)
{
	struct url_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usbd_interface_handle iface;
	usbd_status err;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	struct ifnet *ifp;
	struct mii_data *mii;
	u_char eaddr[ETHER_ADDR_LEN];
	int i, s;

	sc->sc_dev = self;

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

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

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

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

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

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

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

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

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

	s = splnet();

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

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

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

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

	IFQ_SET_READY(&ifp->if_snd);

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

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

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

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

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

	return;

 bad:
	sc->sc_dying = 1;
	return;
}
Exemple #9
0
void 
urio_attach(device_t parent, device_t self, void *aux)
{
	struct urio_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle	dev = uaa->device;
	usbd_interface_handle	iface;
	char			*devinfop;
	usbd_status		err;
	usb_endpoint_descriptor_t *ed;
	u_int8_t		epcount;
	int			i;

	DPRINTFN(10,("urio_attach: sc=%p\n", sc));

	sc->sc_dev = self;

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

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

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

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

	sc->sc_udev = dev;
	sc->sc_iface = iface;

	epcount = 0;
	(void)usbd_endpoint_count(iface, &epcount);

	sc->sc_in_addr = -1;
	sc->sc_out_addr = -1;
	for (i = 0; i < epcount; i++) {
		ed = usbd_interface2endpoint_descriptor(iface, i);
		if (ed == NULL) {
			aprint_error_dev(self, "couldn't get ep %d\n", i);
			return;
		}
		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			sc->sc_in_addr = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			sc->sc_out_addr = ed->bEndpointAddress;
		}
	}
	if (sc->sc_in_addr == -1 || sc->sc_out_addr == -1) {
		aprint_error_dev(self, "missing endpoint\n");
		return;
	}

	DPRINTFN(10, ("urio_attach: %p\n", sc->sc_udev));

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

	return;
}
Exemple #10
0
void
pciattach(device_t parent, device_t self, void *aux)
{
	struct pcibus_attach_args *pba = aux;
	struct pci_softc *sc = device_private(self);
	int io_enabled, mem_enabled, mrl_enabled, mrm_enabled, mwi_enabled;
	const char *sep = "";
	static const int wildcard[PCICF_NLOCS] = {
		PCICF_DEV_DEFAULT, PCICF_FUNCTION_DEFAULT
	};

	sc->sc_dev = self;

	pci_attach_hook(parent, self, pba);

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

	io_enabled = (pba->pba_flags & PCI_FLAGS_IO_OKAY);
	mem_enabled = (pba->pba_flags & PCI_FLAGS_MEM_OKAY);
	mrl_enabled = (pba->pba_flags & PCI_FLAGS_MRL_OKAY);
	mrm_enabled = (pba->pba_flags & PCI_FLAGS_MRM_OKAY);
	mwi_enabled = (pba->pba_flags & PCI_FLAGS_MWI_OKAY);

	if (io_enabled == 0 && mem_enabled == 0) {
		aprint_error_dev(self, "no spaces enabled!\n");
		goto fail;
	}

#define	PRINT(str)							\
do {									\
	aprint_verbose("%s%s", sep, str);				\
	sep = ", ";							\
} while (/*CONSTCOND*/0)

	aprint_verbose_dev(self, "");

	if (io_enabled)
		PRINT("i/o space");
	if (mem_enabled)
		PRINT("memory space");
	aprint_verbose(" enabled");

	if (mrl_enabled || mrm_enabled || mwi_enabled) {
		if (mrl_enabled)
			PRINT("rd/line");
		if (mrm_enabled)
			PRINT("rd/mult");
		if (mwi_enabled)
			PRINT("wr/inv");
		aprint_verbose(" ok");
	}

	aprint_verbose("\n");

#undef PRINT

	sc->sc_iot = pba->pba_iot;
	sc->sc_memt = pba->pba_memt;
	sc->sc_dmat = pba->pba_dmat;
	sc->sc_dmat64 = pba->pba_dmat64;
	sc->sc_pc = pba->pba_pc;
	sc->sc_bus = pba->pba_bus;
	sc->sc_bridgetag = pba->pba_bridgetag;
	sc->sc_maxndevs = pci_bus_maxdevs(pba->pba_pc, pba->pba_bus);
	sc->sc_intrswiz = pba->pba_intrswiz;
	sc->sc_intrtag = pba->pba_intrtag;
	sc->sc_flags = pba->pba_flags;

	device_pmf_driver_set_child_register(sc->sc_dev, pci_child_register);

	pcirescan(sc->sc_dev, "pci", wildcard);

fail:
	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
Exemple #11
0
static void
sony_acpi_attach(device_t parent, device_t self, void *aux)
{
	struct sony_acpi_softc *sc = device_private(self);
	struct acpi_attach_args *aa = aux;
	ACPI_STATUS rv;
	int i;

	aprint_naive(": Sony Miscellaneous Controller\n");
	aprint_normal(": Sony Miscellaneous Controller\n");

	sc->sc_node = aa->aa_node;
	sc->sc_dev = self;

	rv = AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 100,
	    sony_acpi_find_pic, sc, NULL);
	if (ACPI_FAILURE(rv))
		aprint_error_dev(self, "couldn't walk namespace: %s\n",
		    AcpiFormatException(rv));

	/*
	 * If we don't find an SNY6001 device, assume that we need the
	 * Fn key initialization sequence.
	 */
	if (sc->sc_has_pic == false)
		sc->sc_quirks |= SONY_ACPI_QUIRK_FNINIT;

	sony_acpi_quirk_setup(sc);

	/* Configure suspend button and hotkeys */
	sc->sc_smpsw[SONY_PSW_SLEEP].smpsw_name = device_xname(self);
	sc->sc_smpsw[SONY_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP;
	sc->sc_smpsw[SONY_PSW_DISPLAY_CYCLE].smpsw_name =
	    PSWITCH_HK_DISPLAY_CYCLE;
	sc->sc_smpsw[SONY_PSW_DISPLAY_CYCLE].smpsw_type = PSWITCH_TYPE_HOTKEY;
	sc->sc_smpsw[SONY_PSW_ZOOM].smpsw_name = PSWITCH_HK_ZOOM_BUTTON;
	sc->sc_smpsw[SONY_PSW_ZOOM].smpsw_type = PSWITCH_TYPE_HOTKEY;
	sc->sc_smpsw_valid = 1;

	for (i = 0; i < SONY_PSW_LAST; i++)
		if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) {
			aprint_error_dev(self, 
			    "couldn't register %s with sysmon\n",
			    sc->sc_smpsw[i].smpsw_name);
			sc->sc_smpsw_valid = 0;
		}

	/* Install notify handler */
	rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle,
	    ACPI_DEVICE_NOTIFY, sony_acpi_notify_handler, self);
	if (ACPI_FAILURE(rv))
		aprint_error_dev(self,
		    "couldn't install notify handler (%d)\n", rv);

	/* Install sysctl handler */
	rv = AcpiWalkNamespace(ACPI_TYPE_METHOD,
	    sc->sc_node->ad_handle, 1, sony_walk_cb, sc, NULL);
#ifdef DIAGNOSTIC
	if (ACPI_FAILURE(rv))
		aprint_error_dev(self, "Cannot walk ACPI namespace (%d)\n",
		    rv);
#endif

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

	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP,
				 sony_acpi_brightness_up, true))
		aprint_error_dev(self, "couldn't register BRIGHTNESS UP handler\n");

	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN,
				 sony_acpi_brightness_down, true))
		aprint_error_dev(self, "couldn't register BRIGHTNESS DOWN handler\n");
}
Exemple #12
0
static void
pckbc_acpi_attach(device_t parent, device_t self, void *aux)
{
	struct pckbc_acpi_softc *psc = device_private(self);
	struct pckbc_softc *sc = &psc->sc_pckbc;
	struct pckbc_internal *t;
	struct acpi_attach_args *aa = aux;
	bus_space_handle_t ioh_d, ioh_c;
	pckbc_slot_t peer;
	struct acpi_resources res;
	struct acpi_io *io0, *io1, *ioswap;
	struct acpi_irq *irq;
	ACPI_STATUS rv;

	sc->sc_dv = self;
	psc->sc_ic = aa->aa_ic;

	if (acpi_match_hid(aa->aa_node->ad_devinfo, pckbc_acpi_ids_kbd)) {
		psc->sc_slot = PCKBC_KBD_SLOT;
		peer = PCKBC_AUX_SLOT;
	} else if (acpi_match_hid(aa->aa_node->ad_devinfo, pckbc_acpi_ids_ms)) {
		psc->sc_slot = PCKBC_AUX_SLOT;
		peer = PCKBC_KBD_SLOT;
	} else {
		aprint_error(": unknown port!\n");
		panic("pckbc_acpi_attach: impossible");
	}

	aprint_naive("\n");
	aprint_normal(": %s port\n", pckbc_slot_names[psc->sc_slot]);

	/* parse resources */
	rv = acpi_resource_parse(sc->sc_dv, aa->aa_node->ad_handle, "_CRS",
	    &res, &acpi_resource_parse_ops_default);
	if (ACPI_FAILURE(rv))
		return;

	/* find our IRQ */
	irq = acpi_res_irq(&res, 0);
	if (irq == NULL) {
		aprint_error_dev(self, "unable to find irq resource\n");
		goto out;
	}
	psc->sc_irq = irq->ar_irq;
	psc->sc_ist = (irq->ar_type == ACPI_EDGE_SENSITIVE) ? IST_EDGE : IST_LEVEL;

	if (psc->sc_slot == PCKBC_KBD_SLOT)
		first = psc;

	if ((!first || !first->sc_pckbc.id) &&
	    (psc->sc_slot == PCKBC_KBD_SLOT)) {

		io0 = acpi_res_io(&res, 0);
		io1 = acpi_res_io(&res, 1);
		if (io0 == NULL || io1 == NULL) {
			aprint_error_dev(self,
			    "unable to find i/o resources\n");
			goto out;
		}

		/*
		 * JDM: Some firmware doesn't report resources in the order we
		 * expect; sort IO resources here (lowest first)
		 */
		if (io0->ar_base > io1->ar_base) {
			ioswap = io0;
			io0 = io1;
			io1 = ioswap;
		}

		if (pckbc_is_console(aa->aa_iot, io0->ar_base)) {
			t = &pckbc_consdata;
			ioh_d = t->t_ioh_d;
			ioh_c = t->t_ioh_c;
			pckbc_console_attached = 1;
			/* t->t_cmdbyte was initialized by cnattach */
		} else {
			if (bus_space_map(aa->aa_iot, io0->ar_base,
					  io0->ar_length, 0, &ioh_d) ||
			    bus_space_map(aa->aa_iot, io1->ar_base,
					  io1->ar_length, 0, &ioh_c))
				panic("pckbc_acpi_attach: couldn't map");

			t = malloc(sizeof(struct pckbc_internal),
			    M_DEVBUF, M_WAITOK|M_ZERO);
			t->t_iot = aa->aa_iot;
			t->t_ioh_d = ioh_d;
			t->t_ioh_c = ioh_c;
			t->t_addr = io0->ar_base;
			t->t_cmdbyte = KC8_CPU;	/* Enable ports */
			callout_init(&t->t_cleanup, 0);
		}

		t->t_sc = &first->sc_pckbc;
		first->sc_pckbc.id = t;

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

		first->sc_pckbc.intr_establish = pckbc_acpi_intr_establish;
		config_defer(first->sc_pckbc.sc_dv, pckbc_acpi_finish_attach);
	} else if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
 out:
	acpi_resource_cleanup(&res);
}
Exemple #13
0
void
aupciattach(device_t parent, device_t self, void *aux)
{
    struct aupci_softc		*sc = device_private(self);
    struct aubus_attach_args	*aa = (struct aubus_attach_args *)aux;
    uint32_t			cfg;
#if NPCI > 0
    uint32_t			mbar, mask;
    bus_addr_t			mstart;
    struct pcibus_attach_args	pba;
#endif

    aupci_found = 1;

    sc->sc_dev = self;
    sc->sc_bust = aa->aa_st;
    if (bus_space_map(sc->sc_bust, aa->aa_addrs[0], 512, 0,
                      &sc->sc_bush) != 0) {
        aprint_error(": unable to map PCI registers\n");
        return;
    }

#if NPCI > 0
    /*
     * These physical addresses are locked in on the CPUs we have
     * seen.  Perhaps these should be passed in via locators, thru
     * the configuration file.
     */
    sc->sc_cfgbase = PCI_CONFIG_BASE;
    sc->sc_membase = PCI_MEM_BASE;
    sc->sc_iobase = PCI_IO_BASE;
#endif

    /*
     * Configure byte swapping, as YAMON doesn't do it.  YAMON does take
     * care of most of the rest of the details (clocking, etc.), however.
     */
#if _BYTE_ORDER == _BIG_ENDIAN
    /*
     * N.B.: This still doesn't do the DMA thing properly.  I have
     * not yet figured out how to get DMA access to work properly
     * without having bytes swapped while the processor is in
     * big-endian mode.  I'm not even sure that the Alchemy part
     * can do it without swapping the bytes (which would be a
     * bummer, since then only parts which had hardware detection
     * and swapping support would work without special hacks in
     * their drivers.)
     */
    cfg = AUPCI_CONFIG_CH | AUPCI_CONFIG_R1H |
          AUPCI_CONFIG_R2H | AUPCI_CONFIG_AEN |
          AUPCI_CONFIG_SM | AUPCI_CONFIG_ST | AUPCI_CONFIG_SIC_DATA;
#else
    cfg = AUPCI_CONFIG_CH | AUPCI_CONFIG_R1H |
          AUPCI_CONFIG_R2H | AUPCI_CONFIG_AEN;
#endif
    bus_space_write_4(sc->sc_bust, sc->sc_bush, AUPCI_CONFIG, cfg);

    cfg = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_COMMAND_STATUS);

    aprint_normal(": Alchemy Host-PCI Bridge, %sMHz\n",
                  (cfg & PCI_STATUS_66MHZ_SUPPORT) ? "66" : "33");
    aprint_naive("\n");

#if NPCI > 0
    /*
     * PCI configuration space.  Address in this bus are
     * orthogonal to other spaces.  We need to make the entire
     * 32-bit address space available.
     */
    sc->sc_cfgt = &sc->sc_cfg_space;
    au_himem_space_init(sc->sc_cfgt, "pcicfg", sc->sc_cfgbase,
                        0x00000000, 0xffffffff, AU_HIMEM_SPACE_IO);

    /*
     * Virtual PCI memory.  Configured so that we don't overlap
     * with PCI memory space.
     */
    mask = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_MWMASK);
    mask >>= AUPCI_MWMASK_SHIFT;
    mask <<= AUPCI_MWMASK_SHIFT;

    mbar = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_MBAR);
    mstart = (mbar & mask) + (~mask + 1);

    sc->sc_memt = &sc->sc_mem_space;
    au_himem_space_init(sc->sc_memt, "pcimem", sc->sc_membase,
                        mstart, 0xffffffff, AU_HIMEM_SPACE_LITTLE_ENDIAN);

    /*
     * IO space.  Address in this bus are orthogonal to other spaces.
     * 16 MB should be plenty.  We don't start from zero to avoid
     * potential device bugs.
     */
    sc->sc_iot = &sc->sc_io_space;
    au_himem_space_init(sc->sc_iot, "pciio",
                        sc->sc_iobase, AUPCI_IO_START, AUPCI_IO_END,
                        AU_HIMEM_SPACE_LITTLE_ENDIAN | AU_HIMEM_SPACE_IO);

    sc->sc_pc.pc_conf_v = sc;
    sc->sc_pc.pc_attach_hook = aupci_attach_hook;
    sc->sc_pc.pc_bus_maxdevs = aupci_bus_maxdevs;
    sc->sc_pc.pc_make_tag = aupci_make_tag;
    sc->sc_pc.pc_decompose_tag = aupci_decompose_tag;
    sc->sc_pc.pc_conf_read = aupci_conf_read;
    sc->sc_pc.pc_conf_write = aupci_conf_write;

    sc->sc_pc.pc_intr_v = sc;
    sc->sc_pc.pc_intr_map = aupci_intr_map;
    sc->sc_pc.pc_intr_string = aupci_intr_string;
    sc->sc_pc.pc_intr_establish = aupci_intr_establish;
    sc->sc_pc.pc_intr_disestablish = aupci_intr_disestablish;
    sc->sc_pc.pc_conf_interrupt = aupci_conf_interrupt;

#ifdef PCI_NETBSD_CONFIGURE
    mem_ex = extent_create("pcimem", mstart, 0xffffffff,
                           NULL, 0, EX_WAITOK);

    io_ex = extent_create("pciio", AUPCI_IO_START, AUPCI_IO_END,
                          NULL, 0, EX_WAITOK);

    pci_configure_bus(&sc->sc_pc,
                      io_ex, mem_ex, NULL, 0, mips_cache_info.mci_dcache_align);
    extent_destroy(mem_ex);
    extent_destroy(io_ex);
#endif

    pba.pba_iot = sc->sc_iot;
    pba.pba_memt = sc->sc_memt;
    /* XXX: review dma tag logic */
    pba.pba_dmat = aa->aa_dt;
    pba.pba_dmat64 = NULL;
    pba.pba_pc = &sc->sc_pc;
    pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
    pba.pba_bus = 0;
    pba.pba_bridgetag = NULL;

    config_found_ia(self, "pcibus", &pba, pcibusprint);
#endif	/* NPCI > 0 */
}
Exemple #14
0
static void
awin_tcon_attach(device_t parent, device_t self, void *aux)
{
	struct awin_tcon_softc *sc = device_private(self);
	struct awinio_attach_args * const aio = aux;
	const struct awin_locators * const loc = &aio->aio_loc;
	prop_dictionary_t cfg = device_properties(self);
	const char *output;

	sc->sc_dev = self;
	sc->sc_bst = aio->aio_core_bst;
	sc->sc_port = loc->loc_port;
	bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
	bus_space_subregion(sc->sc_bst, aio->aio_ccm_bsh,
	    AWIN_LCD0_CH0_CLK_REG + (loc->loc_port * 4), 4, &sc->sc_ch0clk_bsh);
	bus_space_subregion(sc->sc_bst, aio->aio_ccm_bsh,
	    AWIN_LCD0_CH1_CLK_REG + (loc->loc_port * 4), 4, &sc->sc_ch1clk_bsh);
	if (!tcon_mux_inited) {
		/* the mux register is only in LCD0 */
		bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
		    AWIN_LCD0_OFFSET + AWIN_TCON_MUX_CTL_REG, 4, &tcon_mux_bsh);
		tcon_mux_inited = true;
		/* always enable tcon0, the mux is there */
		awin_tcon_clear_reset(aio, 0);
	}

	if (prop_dictionary_get_cstring_nocopy(cfg, "output", &output)) {
		if (strcmp(output, "hdmi") == 0) {
			sc->sc_output_type = OUTPUT_HDMI;
		} else if (strcmp(output, "lvds") == 0) {
			sc->sc_output_type = OUTPUT_LVDS;
		} else if (strcmp(output, "vga") == 0) {
			sc->sc_output_type = OUTPUT_VGA;
		} else {
			panic("tcon: wrong mode %s", output);
		}
	} else {
		sc->sc_output_type = OUTPUT_HDMI; /* default */
	}

	aprint_naive("\n");
	aprint_normal(": LCD/TV timing controller (TCON%d)\n", loc->loc_port);
	switch (sc->sc_port) {
	case 0:
		awin_pll3_enable();
		sc->sc_clk_pll = 3;
		break;
	case 1:
		awin_pll7_enable();
		sc->sc_clk_pll = 7;
		break;
	default:
		panic("awin_tcon port\n");
	}

	aprint_verbose_dev(self, ": using DEBE%d, pll%d\n",
		    device_unit(self), sc->sc_clk_pll);

	awin_tcon_clear_reset(aio, sc->sc_port);
	
	TCON_WRITE(sc, AWIN_TCON_GCTL_REG, 0);
	TCON_WRITE(sc, AWIN_TCON_GINT0_REG, 0);
	TCON_WRITE(sc, AWIN_TCON_GINT1_REG,
	    __SHIFTIN(0x20, AWIN_TCON_GINT1_TCON0_LINENO));
	TCON_WRITE(sc, AWIN_TCON0_DCLK_REG, 0xf0000000);
	TCON_WRITE(sc, AWIN_TCON0_CTL_REG, 0);
	TCON_WRITE(sc, AWIN_TCON0_IO_TRI_REG, 0xffffffff);
	TCON_WRITE(sc, AWIN_TCON1_CTL_REG, 0);
	TCON_WRITE(sc, AWIN_TCON1_IO_TRI_REG, 0xffffffff);
	if (sc->sc_output_type == OUTPUT_LVDS) {
		awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
		    AWIN_LVDS_CLK_REG, AWIN_LVDS_CLK_ENABLE, 0);
		awin_tcon0_set_video(sc);
	}
}
Exemple #15
0
static void
cac_pci_attach(device_t parent, device_t self, void *aux)
{
    struct pci_attach_args *pa;
    const struct cac_pci_type *ct;
    struct cac_softc *sc;
    pci_chipset_tag_t pc;
    pci_intr_handle_t ih;
    const char *intrstr;
    pcireg_t reg;
    int memr, ior, i;
    char intrbuf[PCI_INTRSTR_LEN];

    aprint_naive(": RAID controller\n");

    sc = device_private(self);
    sc->sc_dev = self;
    pa = (struct pci_attach_args *)aux;
    pc = pa->pa_pc;
    ct = cac_pci_findtype(pa);

    /*
     * Map the PCI register window.
     */
    memr = -1;
    ior = -1;

    for (i = 0x10; i <= 0x14; i += 4) {
        reg = pci_conf_read(pa->pa_pc, pa->pa_tag, i);

        if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) {
            if (ior == -1 && PCI_MAPREG_IO_SIZE(reg) != 0)
                ior = i;
        } else {
            if (memr == -1 && PCI_MAPREG_MEM_SIZE(reg) != 0)
                memr = i;
        }
    }

    if (memr != -1) {
        if (pci_mapreg_map(pa, memr, PCI_MAPREG_TYPE_MEM, 0,
                           &sc->sc_iot, &sc->sc_ioh, NULL, NULL))
            memr = -1;
        else
            ior = -1;
    }
    if (ior != -1)
        if (pci_mapreg_map(pa, ior, PCI_MAPREG_TYPE_IO, 0,
                           &sc->sc_iot, &sc->sc_ioh, NULL, NULL))
            ior = -1;
    if (memr == -1 && ior == -1) {
        aprint_error_dev(self, "can't map i/o or memory space\n");
        return;
    }

    sc->sc_dmat = pa->pa_dmat;

    /* Enable the device. */
    reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
    pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
                   reg | PCI_COMMAND_MASTER_ENABLE);

    /* Map and establish the interrupt. */
    if (pci_intr_map(pa, &ih)) {
        aprint_error("can't map interrupt\n");
        return;
    }
    intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
    sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, cac_intr, sc);
    if (sc->sc_ih == NULL) {
        aprint_error("can't establish interrupt");
        if (intrstr != NULL)
            aprint_error(" at %s", intrstr);
        aprint_error("\n");
        return;
    }

    aprint_normal(": Compaq %s\n", ct->ct_typestr);

    /* Now attach to the bus-independent code. */
    memcpy(&sc->sc_cl, ct->ct_linkage, sizeof(sc->sc_cl));
    cac_init(sc, intrstr, (ct->ct_flags & CT_STARTFW) != 0);
}
Exemple #16
0
void 
ubsa_attach(device_t parent, device_t self, void *aux)
{
	struct ubsa_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usb_config_descriptor_t *cdesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	usbd_status err;
	struct ucom_attach_args uca;
	int i;

	sc->sc_dev = self;

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

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

        sc->sc_udev = dev;
	sc->sc_config_index = UBSA_DEFAULT_CONFIG_INDEX;
	sc->sc_numif = 1; /* default device has one interface */

	/*
	 * initialize rts, dtr variables to something
	 * different from boolean 0, 1
	 */
	sc->sc_dtr = -1;
	sc->sc_rts = -1;

	/*
	 * Quad UMTS cards use different requests to
	 * control com settings and only some.
	 */
	sc->sc_quadumts = 0;
	if (uaa->vendor == USB_VENDOR_OPTIONNV) {
		switch (uaa->product) {
		case USB_PRODUCT_OPTIONNV_QUADUMTS:
		case USB_PRODUCT_OPTIONNV_QUADUMTS2:
			sc->sc_quadumts = 1;
			break;
		}
	}

	DPRINTF(("ubsa attach: sc = %p\n", sc));

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, sc->sc_config_index, 1);
	if (err) {
		aprint_error_dev(self,
		    "failed to set configuration: %s\n",
		    usbd_errstr(err));
		sc->sc_dying = 1;
		goto error;
	}

	/* get the config descriptor */
	cdesc = usbd_get_config_descriptor(sc->sc_udev);

	if (cdesc == NULL) {
		aprint_error_dev(self,
		    "failed to get configuration descriptor\n");
		sc->sc_dying = 1;
		goto error;
	}

	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	/* get the interfaces */
	err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX_OFFSET,
			 &sc->sc_iface[0]);
	if (err) {
		/* can not get main interface */
		sc->sc_dying = 1;
		goto error;
	}

	/* Find the endpoints */
	id = usbd_get_interface_descriptor(sc->sc_iface[0]);
	sc->sc_iface_number[0] = id->bInterfaceNumber;

	/* initialize endpoints */
	uca.bulkin = uca.bulkout = -1;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface[0], i);
		if (ed == NULL) {
			aprint_error_dev(self,
			     "no endpoint descriptor for %d\n", i);
			break;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkin = ed->bEndpointAddress;
			uca.ibufsize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
			uca.obufsize = UGETW(ed->wMaxPacketSize);
		}
	} /* end of Endpoint loop */

	if (sc->sc_intr_number == -1) {
		aprint_error_dev(self, "Could not find interrupt in\n");
		sc->sc_dying = 1;
		goto error;
	}

	if (uca.bulkin == -1) {
		aprint_error_dev(self, "Could not find data bulk in\n");
		sc->sc_dying = 1;
		goto error;
	}

	if (uca.bulkout == -1) {
		aprint_error_dev(self, "Could not find data bulk out\n");
		sc->sc_dying = 1;
		goto error;
	}

	uca.portno = 0;
	/* bulkin, bulkout set above */
	uca.ibufsizepad = uca.ibufsize;
	uca.opkthdrlen = 0;
	uca.device = dev;
	uca.iface = sc->sc_iface[0];
	uca.methods = &ubsa_methods;
	uca.arg = sc;
	uca.info = NULL;
	DPRINTF(("ubsa: int#=%d, in = 0x%x, out = 0x%x, intr = 0x%x\n",
    		i, uca.bulkin, uca.bulkout, sc->sc_intr_number));
	sc->sc_subdevs[0] = config_found_sm_loc(self, "ucombus", NULL, &uca,
				    ucomprint, ucomsubmatch);

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

	return;

error:
	return;
}
static void
acpicpu_attach(device_t parent, device_t self, void *aux)
{
	struct acpicpu_softc *sc = device_private(self);
	struct cpu_info *ci;
	ACPI_HANDLE hdl;
	cpuid_t id;
	int rv;

	ci = acpicpu_md_attach(parent, self, aux);

	if (ci == NULL)
		return;

	sc->sc_ci = ci;
	sc->sc_dev = self;
	sc->sc_cold = true;

	hdl = acpi_match_cpu_info(ci);

	if (hdl == NULL) {
		aprint_normal(": failed to match processor\n");
		return;
	}

	sc->sc_node = acpi_match_node(hdl);

	if (acpicpu_once_attach() != 0) {
		aprint_normal(": failed to initialize\n");
		return;
	}

	KASSERT(acpi_softc != NULL);
	KASSERT(acpicpu_sc != NULL);
	KASSERT(sc->sc_node != NULL);

	id = sc->sc_ci->ci_acpiid;

	if (acpicpu_sc[id] != NULL) {
		aprint_normal(": already attached\n");
		return;
	}

	aprint_naive("\n");
	aprint_normal(": ACPI CPU\n");

	rv = acpicpu_object(sc->sc_node->ad_handle, &sc->sc_object);

	if (ACPI_FAILURE(rv))
		aprint_verbose_dev(self, "failed to obtain CPU object\n");

	acpicpu_count++;
	acpicpu_sc[id] = sc;

	sc->sc_cap = acpicpu_cap(sc);
	sc->sc_ncpus = acpi_md_ncpus();
	sc->sc_flags = acpicpu_md_flags();

	KASSERT(acpicpu_count <= sc->sc_ncpus);
	KASSERT(sc->sc_node->ad_device == NULL);

	sc->sc_node->ad_device = self;
	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);

	acpicpu_cstate_attach(self);
	acpicpu_pstate_attach(self);
	acpicpu_tstate_attach(self);

	acpicpu_debug_print(self);
	acpicpu_evcnt_attach(self);

	(void)config_interrupts(self, acpicpu_start);
	(void)acpi_register_notify(sc->sc_node, acpicpu_notify);
	(void)pmf_device_register(self, acpicpu_suspend, acpicpu_resume);
}
Exemple #18
0
static void
sdhc_attach(device_t parent, device_t self, void *aux)
{
	struct sdhc_axi_softc *sc = device_private(self);
	struct axi_attach_args *aa = aux;
	bus_space_tag_t iot = aa->aa_iot;
	bus_space_handle_t ioh;
	u_int perclk = 0, v;

	sc->sc_sdhc.sc_dev = self;
	sc->sc_sdhc.sc_dmat = aa->aa_dmat;

	if (bus_space_map(iot, aa->aa_addr, AIPS2_USDHC_SIZE, 0, &ioh)) {
		aprint_error_dev(self, "can't map\n");
		return;
	}

	aprint_normal(": Ultra Secured Digial Host Controller\n");
	aprint_naive("\n");
	sc->sc_sdhc.sc_host = sc->sc_hosts;

	switch (aa->aa_addr) {
	case IMX6_AIPS2_BASE + AIPS2_USDHC1_BASE:
		v = imx6_ccm_read(CCM_CCGR6);
		imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC1_CLK_ENABLE(3));
		perclk = imx6_get_clock(IMX6CLK_USDHC1);
		imx6_set_gpio(self, "usdhc1-cd-gpio", &sc->sc_gpio_cd,
		    &sc->sc_gpio_cd_active, GPIO_DIR_IN);
		break;
	case IMX6_AIPS2_BASE + AIPS2_USDHC2_BASE:
		v = imx6_ccm_read(CCM_CCGR6);
		imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC2_CLK_ENABLE(3));
		perclk = imx6_get_clock(IMX6CLK_USDHC2);
		imx6_set_gpio(self, "usdhc2-cd-gpio", &sc->sc_gpio_cd,
		    &sc->sc_gpio_cd_active, GPIO_DIR_IN);
		break;
	case IMX6_AIPS2_BASE + AIPS2_USDHC3_BASE:
		v = imx6_ccm_read(CCM_CCGR6);
		imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC3_CLK_ENABLE(3));
		perclk = imx6_get_clock(IMX6CLK_USDHC3);
		imx6_set_gpio(self, "usdhc3-cd-gpio", &sc->sc_gpio_cd,
		    &sc->sc_gpio_cd_active, GPIO_DIR_IN);
		break;
	case IMX6_AIPS2_BASE + AIPS2_USDHC4_BASE:
		v = imx6_ccm_read(CCM_CCGR6);
		imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC4_CLK_ENABLE(3));
		perclk = imx6_get_clock(IMX6CLK_USDHC4);
		imx6_set_gpio(self, "usdhc4-cd-gpio", &sc->sc_gpio_cd,
		    &sc->sc_gpio_cd_active, GPIO_DIR_IN);
		break;
	}

	sc->sc_sdhc.sc_clkbase = perclk / 1000;
	sc->sc_sdhc.sc_flags |=
	    SDHC_FLAG_USE_DMA |
	    SDHC_FLAG_NO_PWR0 |
	    SDHC_FLAG_HAVE_DVS |
	    SDHC_FLAG_32BIT_ACCESS |
	    SDHC_FLAG_8BIT_MODE |
	    SDHC_FLAG_USE_ADMA2 |
	    SDHC_FLAG_POLL_CARD_DET |
	    SDHC_FLAG_USDHC;

	sc->sc_ih = intr_establish(aa->aa_irq, IPL_SDMMC, IST_LEVEL,
	    sdhc_intr, &sc->sc_sdhc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "can't establish interrupt\n");
		return;
	}

	sc->sc_sdhc.sc_vendor_card_detect = imx6_sdhc_card_detect;
	if (sdhc_host_found(&sc->sc_sdhc, iot, ioh, AIPS2_USDHC_SIZE)) {
		aprint_error_dev(self, "can't initialize host\n");
		return;
	}

	if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume,
	    sdhc_shutdown)) {
		aprint_error_dev(self, "can't establish power hook\n");
	}
}
Exemple #19
0
static void
thinkpad_attach(device_t parent, device_t self, void *opaque)
{
	thinkpad_softc_t *sc = device_private(self);
	struct acpi_attach_args *aa = (struct acpi_attach_args *)opaque;
	struct sysmon_pswitch *psw;
	device_t curdev;
	ACPI_STATUS rv;
	ACPI_INTEGER val;
	int i;

	sc->sc_node = aa->aa_node;
	sc->sc_dev = self;
	sc->sc_display_state = THINKPAD_DISPLAY_LCD;

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

	/* T61 uses \UCMS method for issuing CMOS commands */
	rv = AcpiGetHandle(NULL, "\\UCMS", &sc->sc_cmoshdl);
	if (ACPI_FAILURE(rv))
		sc->sc_cmoshdl_valid = false;
	else {
		aprint_verbose_dev(self, "using CMOS at \\UCMS\n");
		sc->sc_cmoshdl_valid = true;
	}

	sc->sc_ecdev = NULL;
	TAILQ_FOREACH(curdev, &alldevs, dv_list)
		if (device_is_a(curdev, "acpiecdt") ||
		    device_is_a(curdev, "acpiec")) {
			sc->sc_ecdev = curdev;
			break;
		}
	if (sc->sc_ecdev)
		aprint_verbose_dev(self, "using EC at %s\n",
		    device_xname(sc->sc_ecdev));

	/* Get the supported event mask */
	rv = acpi_eval_integer(sc->sc_node->ad_handle, "MHKA", &val);
	if (ACPI_FAILURE(rv)) {
		aprint_error_dev(self, "couldn't evaluate MHKA: %s\n",
		    AcpiFormatException(rv));
		goto fail;
	}

	/* Enable all supported events */
	rv = thinkpad_mask_init(sc, val);
	if (ACPI_FAILURE(rv)) {
		aprint_error_dev(self, "couldn't set event mask: %s\n",
		    AcpiFormatException(rv));
		goto fail;
	}

	/* Install notify handler for events */
	rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle,
	    ACPI_DEVICE_NOTIFY, thinkpad_notify_handler, sc);
	if (ACPI_FAILURE(rv))
		aprint_error_dev(self, "couldn't install notify handler: %s\n",
		    AcpiFormatException(rv));

	/* Register power switches with sysmon */
	psw = sc->sc_smpsw;
	sc->sc_smpsw_valid = true;

	psw[TP_PSW_SLEEP].smpsw_name = device_xname(self);
	psw[TP_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP;
#if notyet
	psw[TP_PSW_HIBERNATE].smpsw_name = device_xname(self);
	mpsw[TP_PSW_HIBERNATE].smpsw_type = PSWITCH_TYPE_HIBERNATE;
#endif
	for (i = TP_PSW_DISPLAY_CYCLE; i < TP_PSW_LAST; i++)
		sc->sc_smpsw[i].smpsw_type = PSWITCH_TYPE_HOTKEY;
	psw[TP_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE;
	psw[TP_PSW_LOCK_SCREEN].smpsw_name = PSWITCH_HK_LOCK_SCREEN;
	psw[TP_PSW_BATTERY_INFO].smpsw_name = PSWITCH_HK_BATTERY_INFO;
	psw[TP_PSW_EJECT_BUTTON].smpsw_name = PSWITCH_HK_EJECT_BUTTON;
	psw[TP_PSW_ZOOM_BUTTON].smpsw_name = PSWITCH_HK_ZOOM_BUTTON;
	psw[TP_PSW_VENDOR_BUTTON].smpsw_name = PSWITCH_HK_VENDOR_BUTTON;

	for (i = 0; i < TP_PSW_LAST; i++) {
		/* not supported yet */
		if (i == TP_PSW_HIBERNATE)
			continue;
		if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) {
			aprint_error_dev(self,
			    "couldn't register with sysmon\n");
			sc->sc_smpsw_valid = false;
			break;
		}
	}

	/* Register temperature and fan sensors with envsys */
	thinkpad_sensors_init(sc);

fail:
	if (!pmf_device_register(self, NULL, thinkpad_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP,
	    thinkpad_brightness_up, true))
		aprint_error_dev(self, "couldn't register event handler\n");
	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN,
	    thinkpad_brightness_down, true))
		aprint_error_dev(self, "couldn't register event handler\n");
}
Exemple #20
0
/* ARGSUSED */
void
flash_attach(device_t parent, device_t self, void *aux)
{
	struct flash_softc * const sc = device_private(self);
	struct flash_attach_args * const faa = aux;
	char pbuf[2][sizeof("9999 KB")];

	sc->sc_dev = self;
	sc->sc_parent_dev = parent;
	sc->flash_if = faa->flash_if;
	sc->sc_partinfo = faa->partinfo;
	sc->hw_softc = device_private(parent);

	format_bytes(pbuf[0], sizeof(pbuf[0]), sc->sc_partinfo.part_size);
	format_bytes(pbuf[1], sizeof(pbuf[1]), sc->flash_if->erasesize);

	aprint_naive("\n");

	switch (sc->flash_if->type) {
	case FLASH_TYPE_NOR:
		aprint_normal(": NOR flash partition size %s, offset %#jx",
			pbuf[0], (uintmax_t )sc->sc_partinfo.part_offset);
		break;

	case FLASH_TYPE_NAND:
		aprint_normal(": NAND flash partition size %s, offset %#jx",
			pbuf[0], (uintmax_t )sc->sc_partinfo.part_offset);
		break;

	default:
		aprint_normal(": %s unknown flash", pbuf[0]);
	}

	if (sc->sc_partinfo.part_flags & FLASH_PART_READONLY) {
		sc->sc_readonly = true;
		aprint_normal(", read only");
	} else {
		sc->sc_readonly = false;
	}

	aprint_normal("\n");

	if (sc->sc_partinfo.part_size == 0) {
		aprint_error_dev(self,
		    "partition size must be larger than 0\n");
		return;
	}

	switch (sc->flash_if->type) {
	case FLASH_TYPE_NOR:
		aprint_normal_dev(sc->sc_dev,
		    "erase size %s bytes, write size %d bytes\n",
		    pbuf[1], sc->flash_if->writesize);
		break;

	case FLASH_TYPE_NAND:
	default:
		aprint_normal_dev(sc->sc_dev,
		    "erase size %s, page size %d bytes, write size %d bytes\n",
		    pbuf[1], sc->flash_if->page_size,
		    sc->flash_if->writesize);
		break;
	}

	if (!pmf_device_register1(sc->sc_dev, NULL, NULL, flash_shutdown))
		aprint_error_dev(sc->sc_dev,
		    "couldn't establish power handler\n");
}
Exemple #21
0
static void
obiosdhc_attach(device_t parent, device_t self, void *aux)
{
    struct obiosdhc_softc * const sc = device_private(self);
    struct obio_attach_args * const oa = aux;
    prop_dictionary_t prop = device_properties(self);
    uint32_t clkd, stat;
    int error, timo, clksft, n;
    bool support8bit = false;
    const char *transfer_mode = "PIO";
#ifdef TI_AM335X
    size_t i;
#endif

    prop_dictionary_get_bool(prop, "8bit", &support8bit);

    sc->sc.sc_dmat = oa->obio_dmat;
    sc->sc.sc_dev = self;
    sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS;
    sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON;
    sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC;
    sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY;
    if (support8bit)
        sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE;
#ifdef TI_AM335X
    sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET;
    sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
#endif
#if defined(OMAP_3530)
    sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
#endif
    sc->sc.sc_host = sc->sc_hosts;
    sc->sc.sc_clkbase = 96000;	/* 96MHZ */
    if (!prop_dictionary_get_uint32(prop, "clkmask", &sc->sc.sc_clkmsk))
        sc->sc.sc_clkmsk = 0x0000ffc0;
    sc->sc.sc_vendor_rod = obiosdhc_rod;
    sc->sc.sc_vendor_write_protect = obiosdhc_write_protect;
    sc->sc.sc_vendor_card_detect = obiosdhc_card_detect;
    sc->sc.sc_vendor_bus_clock = obiosdhc_bus_clock;
    sc->sc_bst = oa->obio_iot;

    clksft = ffs(sc->sc.sc_clkmsk) - 1;

    error = bus_space_map(sc->sc_bst, oa->obio_addr, oa->obio_size, 0,
                          &sc->sc_bsh);
    if (error) {
        aprint_error_dev(self,
                         "can't map registers: %d\n", error);
        return;
    }

    bus_space_subregion(sc->sc_bst, sc->sc_bsh, OMAP3_SDMMC_SDHC_OFFSET,
                        OMAP3_SDMMC_SDHC_SIZE, &sc->sc_sdhc_bsh);

#if NEDMA > 0
    if (oa->obio_edmabase != -1) {
        cv_init(&sc->sc_edma_cv, "sdhcedma");
        sc->sc_edma_fifo = oa->obio_addr +
                           OMAP3_SDMMC_SDHC_OFFSET + SDHC_DATA;
        obiosdhc_edma_init(sc, oa->obio_edmabase);
        sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
        sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA;
        sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN;
        sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
        sc->sc.sc_vendor_transfer_data_dma = obiosdhc_edma_xfer_data;
        transfer_mode = "EDMA";
    }
#endif

    aprint_naive("\n");
    aprint_normal(": SDHC controller (%s)\n", transfer_mode);

#ifdef TI_AM335X
    /* XXX Not really AM335X-specific.  */
    for (i = 0; i < __arraycount(am335x_sdhc); i++)
        if ((oa->obio_addr == am335x_sdhc[i].as_base_addr) &&
                (oa->obio_intr == am335x_sdhc[i].as_intr)) {
            prcm_module_enable(&am335x_sdhc[i].as_module);
            break;
        }
    KASSERT(i < __arraycount(am335x_sdhc));
#endif

    /* XXXXXX: Turn-on regulator via I2C. */
    /* XXXXXX: And enable ICLOCK/FCLOCK. */

    /* MMCHS Soft reset */
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
                      SYSCONFIG_SOFTRESET);
    timo = 3000000;	/* XXXX 3 sec. */
    while (timo--) {
        if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) &
                SYSSTATUS_RESETDONE)
            break;
        delay(1);
    }
    if (timo == 0)
        aprint_error_dev(self, "Soft reset timeout\n");
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
                      SYSCONFIG_ENAWAKEUP | SYSCONFIG_AUTOIDLE | SYSCONFIG_SIDLEMODE_AUTO |
                      SYSCONFIG_CLOCKACTIVITY_FCLK | SYSCONFIG_CLOCKACTIVITY_ICLK);

    sc->sc_ih = intr_establish(oa->obio_intr, IPL_VM, IST_LEVEL,
                               sdhc_intr, &sc->sc);
    if (sc->sc_ih == NULL) {
        aprint_error_dev(self, "failed to establish interrupt %d\n",
                         oa->obio_intr);
        goto fail;
    }

    error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh,
                            oa->obio_size - OMAP3_SDMMC_SDHC_OFFSET);
    if (error != 0) {
        aprint_error_dev(self, "couldn't initialize host, error=%d\n",
                         error);
        goto fail;
    }

    /* Set SDVS 1.8v and DTW 1bit mode */
    SDHC_WRITE(sc, SDHC_HOST_CTL,
               SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8));
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_OD);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE |
               SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_HOST_CTL,
               SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);

    /*
     * 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start
     * from 'OMAP35x Applications Processor  Technical Reference Manual'.
     *
     * During the INIT procedure, the MMCHS controller generates 80 clock
     * periods. In order to keep the 1ms gap, the MMCHS controller should
     * be configured to generate a clock whose frequency is smaller or
     * equal to 80 KHz.
     */

    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
    clkd = CLKD(80);
    n = 1;
    while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) {
        clkd >>= 1;
        n <<= 1;
    }
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft));
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);

    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT);
    for (; n > 0; n--) {
        SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000);
        timo = 3000000;	/* XXXX 3 sec. */
        stat = 0;
        while (!(stat & SDHC_COMMAND_COMPLETE)) {
            stat = SDHC_READ(sc, SDHC_NINTR_STATUS);
            if (--timo == 0)
                break;
            delay(1);
        }
        if (timo == 0) {
            aprint_error_dev(self, "INIT Procedure timeout\n");
            break;
        }
        SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat);
    }
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);

    return;

fail:
    if (sc->sc_ih) {
        intr_disestablish(sc->sc_ih);
        sc->sc_ih = NULL;
    }
    bus_space_unmap(sc->sc_bst, sc->sc_bsh, oa->obio_size);
}
Exemple #22
0
/*
 * Attach the interface. Allocate softc structures, do
 * setup and ethernet/BPF attach.
 */
void
kue_attach(device_t parent, device_t self, void *aux)
{
	struct kue_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	char			*devinfop;
	int			s;
	struct ifnet		*ifp;
	usbd_device_handle	dev = uaa->device;
	usbd_interface_handle	iface;
	usbd_status		err;
	usb_interface_descriptor_t	*id;
	usb_endpoint_descriptor_t	*ed;
	int			i;

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

	sc->kue_dev = self;

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

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

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

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

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

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

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

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

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

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

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

	s = splnet();

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

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

	IFQ_SET_READY(&ifp->if_snd);

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

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

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

	return;
}
Exemple #23
0
void
smsc_attach(device_t parent, device_t self, void *aux)
{
    struct smsc_softc *sc = device_private(self);
    struct usb_attach_arg *uaa = aux;
    usbd_device_handle dev = uaa->device;
    usb_interface_descriptor_t *id;
    usb_endpoint_descriptor_t *ed;
    char *devinfop;
    struct mii_data *mii;
    struct ifnet *ifp;
    int err, s, i;
    uint32_t mac_h, mac_l;

    sc->sc_dev = self;
    sc->sc_udev = dev;

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

    devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
    aprint_normal_dev(self, "%s\n", devinfop);
    usbd_devinfo_free(devinfop);

    err = usbd_set_config_no(dev, SMSC_CONFIG_INDEX, 1);
    if (err) {
        aprint_error_dev(self, "failed to set configuration"
                         ", err=%s\n", usbd_errstr(err));
        return;
    }
    /* Setup the endpoints for the SMSC LAN95xx device(s) */
    usb_init_task(&sc->sc_tick_task, smsc_tick_task, sc, 0);
    usb_init_task(&sc->sc_stop_task, (void (*)(void *))smsc_stop, sc, 0);
    mutex_init(&sc->sc_mii_lock, MUTEX_DEFAULT, IPL_NONE);

    err = usbd_device2interface_handle(dev, SMSC_IFACE_IDX, &sc->sc_iface);
    if (err) {
        aprint_error_dev(self, "getting interface handle failed\n");
        return;
    }

    id = usbd_get_interface_descriptor(sc->sc_iface);

    if (sc->sc_udev->speed >= USB_SPEED_HIGH)
        sc->sc_bufsz = SMSC_MAX_BUFSZ;
    else
        sc->sc_bufsz = SMSC_MIN_BUFSZ;

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

    s = splnet();

    ifp = &sc->sc_ec.ec_if;
    ifp->if_softc = sc;
    strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    ifp->if_init = smsc_init;
    ifp->if_ioctl = smsc_ioctl;
    ifp->if_start = smsc_start;
    ifp->if_stop = smsc_stop;

#ifdef notyet
    /*
     * We can do TCPv4, and UDPv4 checksums in hardware.
     */
    ifp->if_capabilities |=
        /*IFCAP_CSUM_TCPv4_Tx |*/ IFCAP_CSUM_TCPv4_Rx |
        /*IFCAP_CSUM_UDPv4_Tx |*/ IFCAP_CSUM_UDPv4_Rx;
#endif

    sc->sc_ec.ec_capabilities = ETHERCAP_VLAN_MTU;

    /* Setup some of the basics */
    sc->sc_phyno = 1;

    /*
     * Attempt to get the mac address, if an EEPROM is not attached this
     * will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC
     * address based on urandom.
     */
    memset(sc->sc_enaddr, 0xff, ETHER_ADDR_LEN);

    prop_dictionary_t dict = device_properties(self);
    prop_data_t eaprop = prop_dictionary_get(dict, "mac-address");

    if (eaprop != NULL) {
        KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA);
        KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN);
        memcpy(sc->sc_enaddr, prop_data_data_nocopy(eaprop),
               ETHER_ADDR_LEN);
    } else
        /* Check if there is already a MAC address in the register */
        if ((smsc_read_reg(sc, SMSC_MAC_ADDRL, &mac_l) == 0) &&
                (smsc_read_reg(sc, SMSC_MAC_ADDRH, &mac_h) == 0)) {
            sc->sc_enaddr[5] = (uint8_t)((mac_h >> 8) & 0xff);
            sc->sc_enaddr[4] = (uint8_t)((mac_h) & 0xff);
            sc->sc_enaddr[3] = (uint8_t)((mac_l >> 24) & 0xff);
            sc->sc_enaddr[2] = (uint8_t)((mac_l >> 16) & 0xff);
            sc->sc_enaddr[1] = (uint8_t)((mac_l >> 8) & 0xff);
            sc->sc_enaddr[0] = (uint8_t)((mac_l) & 0xff);
        }
static void
virtio_attach(device_t parent, device_t self, void *aux)
{
	struct virtio_softc *sc = device_private(self);
	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t tag = pa->pa_tag;
	int revision;
	pcireg_t id;
	char const *intrstr;
	pci_intr_handle_t ih;

	revision = PCI_REVISION(pa->pa_class);
	if (revision != 0) {
		aprint_normal(": unknown revision 0x%02x; giving up\n",
			      revision);
		return;
	}
	aprint_normal("\n");
	aprint_naive("\n");

	/* subsystem ID shows what I am */
	id = pci_conf_read(pc, tag, PCI_SUBSYS_ID_REG);
	aprint_normal_dev(self, "Virtio %s Device (rev. 0x%02x)\n",
			  (PCI_PRODUCT(id) < NDEVNAMES?
			   virtio_device_name[PCI_PRODUCT(id)] : "Unknown"),
			  revision);

	sc->sc_dev = self;
	sc->sc_pc = pc;
	sc->sc_tag = tag;
	sc->sc_iot = pa->pa_iot;
	sc->sc_dmat = pa->pa_dmat;
	sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;

	if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0,
			   &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	virtio_device_reset(sc);
	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);

	/* XXX: use softc as aux... */
	sc->sc_childdevid = PCI_PRODUCT(id);
	sc->sc_child = NULL;
	config_found(self, sc, NULL);
	if (sc->sc_child == NULL) {
		aprint_error_dev(self,
				 "no matching child driver; not configured\n");
		return;
	}
	if (sc->sc_child == (void*)1) { /* this shows error */
		aprint_error_dev(self,
				 "virtio configuration failed\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}

	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, sc->sc_ipl, virtio_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);

	return;
}
Exemple #25
0
void
ahc_isa_attach(device_t parent, device_t self, void *aux)
{
	struct ahc_softc *ahc = device_private(self);
	struct isa_attach_args *ia = aux;
	bus_space_tag_t iot = ia->ia_iot;
	bus_space_handle_t ioh;
	int irq, intrtype;
	const char *intrtypestr;
	char idstring[EISA_IDSTRINGLEN];
	u_char intdef;

	ahc->sc_dev = self;
	aprint_naive(": SCSI controller\n");

	if (bus_space_map(iot, ia->ia_io[0].ir_addr, ia->ia_io[0].ir_size,
	    0, &ioh)) {
		aprint_error(": can't map i/o space\n");
		return;
	}
	if (!ahc_isa_idstring(iot, ioh, idstring)) {
		aprint_error(": can't read ID string\n");
		goto free_io;
	}
	if ((irq = ahc_aic77xx_irq(iot, ioh)) < 0) {
		aprint_error(": ahc_aic77xx_irq failed\n");
		goto free_io;
	}

	if (strcmp(idstring, "ADP7756") == 0) {
		aprint_normal(": %s\n", EISA_PRODUCT_ADP7756);
	} else if (strcmp(idstring, "ADP7757") == 0) {
		aprint_normal(": %s\n", EISA_PRODUCT_ADP7757);
	} else {
		aprint_error(": unknown device type %s\n", idstring);
		goto free_io;
	}

	/*
	 * Tell the bus-DMA interface that we can do 32bit DMA
	 * NOTE: this variable is first referenced in ahc_init().
	 */
	ahc->sc_dmaflags = ISABUS_DMA_32BIT;

	ahc_set_name(ahc, device_xname(ahc->sc_dev));
	ahc->parent_dmat = ia->ia_dmat;
	ahc->channel = 'A';
	ahc->chip =  AHC_AIC7770|AHC_VL;
	ahc->features = AHC_AIC7770_FE;
	ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
	ahc->flags |= AHC_PAGESCBS;
	ahc->tag = iot;
	ahc->bsh = ioh;

	if (ahc_softc_init(ahc) != 0)
		goto free_io;

	ahc_intr_enable(ahc, false);

	if (ahc_reset(ahc) != 0)
		goto free_io;

	intdef = bus_space_read_1(iot, ioh, INTDEF);

	if (intdef & EDGE_TRIG) {
		intrtype = IST_EDGE;
		intrtypestr = "edge triggered";
	} else {
		intrtype = IST_LEVEL;
		intrtypestr = "level sensitive";
	}
	ahc->ih = isa_intr_establish(ia->ia_ic, irq,
	    intrtype, IPL_BIO, ahc_intr, ahc);
	if (ahc->ih == NULL) {
		aprint_error_dev(ahc->sc_dev,
		    "couldn't establish %s interrupt\n", intrtypestr);
		goto free_io;
	}

	/*
	 * Tell the user what type of interrupts we're using.
	 * useful for debugging irq problems
	 */
	if (bootverbose) {
		aprint_verbose_dev(ahc->sc_dev, "Using %s interrupts\n",
		       intrtypestr);
	}

	/*
	 * Now that we know we own the resources we need, do the
	 * card initialization.
	 */
	aha2840_load_seeprom(ahc);

	/* Attach sub-devices */
	if (ahc_aic77xx_attach(ahc) == 0)
		return; /* succeed */

	/* failed */
	isa_intr_disestablish(ia->ia_ic, ahc->ih);
free_io:
	bus_space_unmap(iot, ioh, ia->ia_io[0].ir_size);
}
void
omapmputmr_attach(device_t parent, device_t self, void *aux)
{
	struct omapmputmr_softc *sc = device_private(self);
	struct tipb_attach_args *tipb = aux;
	int ints_per_sec;

	sc->sc_iot = tipb->tipb_iot;
	sc->sc_intr = tipb->tipb_intr;

	if (bus_space_map(tipb->tipb_iot, tipb->tipb_addr, tipb->tipb_size, 0,
			 &sc->sc_ioh))
		panic("%s: Cannot map registers", device_xname(self));

	switch (device_unit(self)) {
	case 0:
		clock_sc = sc;
		ints_per_sec = hz;
		break;
	case 1:
		stat_sc = sc;
		ints_per_sec = profhz = stathz = STATHZ;
		break;
	case 2:
		ref_sc = sc;
		ints_per_sec = hz;	/* Same rate as clock */
		break;
	default:
		ints_per_sec = hz;	/* Better value? */
		break;
	}

	aprint_normal(": OMAP MPU Timer\n");
	aprint_naive("\n");

	/* Stop the timer from counting, but keep the timer module working. */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_CNTL_TIMER,
			  MPU_CLOCK_ENABLE);

	timer_factors tf;
	calc_timer_factors(ints_per_sec, &tf);

	switch (device_unit(self)) {
	case 0:
		counts_per_hz = tf.reload + 1;
		counts_per_usec = tf.counts_per_usec;
		break;
	case 2:

		/*
		 * The microtime reference clock for all practical purposes
		 * just wraps around as an unsigned int.
		 */

		tf.reload = 0xffffffff;
		break;

	default:
		break;
	}

	/* Set the reload value. */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_LOAD_TIMER, tf.reload);
	/* Set the PTV and the other required bits and pieces. */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_CNTL_TIMER,
			  ( MPU_CLOCK_ENABLE
			    | (tf.ptv << MPU_PTV_SHIFT)
			    | MPU_AR
			    | MPU_ST));
	/* The clock is now running, but is not generating interrupts. */
}
Exemple #27
0
static void
bce_attach(device_t parent, device_t self, void *aux)
{
	struct bce_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	const struct bce_product *bp;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char     *intrstr = NULL;
	uint32_t	command;
	pcireg_t	memtype, pmode;
	bus_addr_t	memaddr;
	bus_size_t	memsize;
	void		*kva;
	bus_dma_segment_t seg;
	int             error, i, pmreg, rseg;
	struct ifnet   *ifp;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->bce_dev = self;

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

	sc->bce_pa = *pa;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	if (pmf_device_register(self, NULL, bce_resume))
		pmf_class_network_register(self, ifp);
	else
		aprint_error_dev(self, "couldn't establish power handler\n");
}
static void
ahd_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args	*pa = aux;
	struct ahd_softc       	*ahd = device_private(self);

	const struct ahd_pci_identity *entry;

	uint32_t	   	devconfig;
	pcireg_t	   	command;
	int		   	error;
	pcireg_t	   	subid;
	uint16_t	   	subvendor;
	pcireg_t           	reg;
	int		   	ioh_valid, ioh2_valid, memh_valid;
	pcireg_t           	memtype;
	pci_intr_handle_t  	ih;
	const char         	*intrstr;
	struct ahd_pci_busdata 	*bd;

	ahd->sc_dev = self;
	ahd_set_name(ahd, device_xname(self));
	ahd->parent_dmat = pa->pa_dmat;

	command = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	entry = ahd_find_pci_device(pa->pa_id, subid);
	if (entry == NULL)
		return;

	/* Keep information about the PCI bus */
	bd = malloc(sizeof (struct ahd_pci_busdata), M_DEVBUF, M_NOWAIT);
	if (bd == NULL) {
		aprint_error("%s: unable to allocate bus-specific data\n",
		    ahd_name(ahd));
		return;
	}
	memset(bd, 0, sizeof(struct ahd_pci_busdata));

	bd->pc = pa->pa_pc;
	bd->tag = pa->pa_tag;
	bd->func = pa->pa_function;
	bd->dev = pa->pa_device;

	ahd->bus_data = bd;

	ahd->description = entry->name;

	ahd->seep_config = malloc(sizeof(*ahd->seep_config),
				  M_DEVBUF, M_NOWAIT);
	if (ahd->seep_config == NULL) {
		aprint_error("%s: cannot malloc seep_config!\n", ahd_name(ahd));
		return;
	}
	memset(ahd->seep_config, 0, sizeof(*ahd->seep_config));

	LIST_INIT(&ahd->pending_scbs);
	ahd_timer_init(&ahd->reset_timer);
	ahd_timer_init(&ahd->stat_timer);
	ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A
	    | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A;
	ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
	ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
	ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
	ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT;
	ahd->int_coalescing_stop_threshold =
	    AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT;

	if (ahd_platform_alloc(ahd, NULL) != 0) {
                ahd_free(ahd);
                return;
        }

	/*
	 * Record if this is an HP board.
	 */
	subvendor = PCI_VENDOR(subid);
	if (subvendor == SUBID_HP)
		ahd->flags |= AHD_HP_BOARD;

	error = entry->setup(ahd, pa);
	if (error != 0)
		return;

	devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
	if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
		ahd->chip |= AHD_PCI;
		/* Disable PCIX workarounds when running in PCI mode. */
		ahd->bugs &= ~AHD_PCIX_BUG_MASK;
	} else {
		ahd->chip |= AHD_PCIX;
	}
	ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];

	memh_valid = ioh_valid = ioh2_valid = 0;

	if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX,
	    &bd->pcix_off, NULL)) {
		if (ahd->chip & AHD_PCIX)
			aprint_error_dev(self,
			    "warning: can't find PCI-X capability\n");
		ahd->chip &= ~AHD_PCIX;
		ahd->chip |= AHD_PCI;
		ahd->bugs &= ~AHD_PCIX_BUG_MASK;
	}

	/*
	 * Map PCI Registers
	 */
	if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) {
		memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
					  AHD_PCI_MEMADDR);
		switch (memtype) {
		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
			memh_valid = (pci_mapreg_map(pa, AHD_PCI_MEMADDR,
						     memtype, 0, &ahd->tags[0],
						     &ahd->bshs[0],
						     NULL, NULL) == 0);
			if (memh_valid) {
				ahd->tags[1] = ahd->tags[0];
				bus_space_subregion(ahd->tags[0], ahd->bshs[0],
						    /*offset*/0x100,
						    /*size*/0x100,
						    &ahd->bshs[1]);
				if (ahd_pci_test_register_access(ahd) != 0)
					memh_valid = 0;
			}
			break;
		default:
			memh_valid = 0;
			aprint_error("%s: unknown memory type: 0x%x\n",
			       ahd_name(ahd), memtype);
			break;
		}

		if (memh_valid) {
			command &= ~PCI_COMMAND_IO_ENABLE;
                        pci_conf_write(pa->pa_pc, pa->pa_tag,
                        	       PCI_COMMAND_STATUS_REG, command);
		}
#ifdef AHD_DEBUG
		printf("%s: doing memory mapping shs0 0x%lx, shs1 0x%lx\n",
		    ahd_name(ahd), ahd->bshs[0], ahd->bshs[1]);
#endif
	}

	if (command & PCI_COMMAND_IO_ENABLE) {
		/* First BAR */
		ioh_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR,
					    PCI_MAPREG_TYPE_IO, 0,
					    &ahd->tags[0], &ahd->bshs[0],
					    NULL, NULL) == 0);

		/* 2nd BAR */
		ioh2_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR1,
					     PCI_MAPREG_TYPE_IO, 0,
					     &ahd->tags[1], &ahd->bshs[1],
					     NULL, NULL) == 0);

		if (ioh_valid && ioh2_valid) {
			KASSERT(memh_valid == 0);
			command &= ~PCI_COMMAND_MEM_ENABLE;
                        pci_conf_write(pa->pa_pc, pa->pa_tag,
                        	       PCI_COMMAND_STATUS_REG, command);
		}
#ifdef AHD_DEBUG
		printf("%s: doing io mapping shs0 0x%lx, shs1 0x%lx\n",
		    ahd_name(ahd), ahd->bshs[0], ahd->bshs[1]);
#endif

	}

	if (memh_valid == 0 && (ioh_valid == 0 || ioh2_valid == 0)) {
		aprint_error("%s: unable to map registers\n", ahd_name(ahd));
		return;
	}

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

	/* power up chip */
	if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self,
	    pci_activate_null)) && error != EOPNOTSUPP) {
		aprint_error_dev(self, "cannot activate %d\n", error);
		return;
	}
	/*
         * Should we bother disabling 39Bit addressing
         * based on installed memory?
         */
        if (sizeof(bus_addr_t) > 4)
        	ahd->flags |= AHD_39BIT_ADDRESSING;

	/*
	 * If we need to support high memory, enable dual
	 * address cycles.  This bit must be set to enable
	 * high address bit generation even if we are on a
	 * 64bit bus (PCI64BIT set in devconfig).
	 */
	if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
		uint32_t dvconfig;

		aprint_normal("%s: Enabling 39Bit Addressing\n", ahd_name(ahd));
		dvconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
		dvconfig |= DACEN;
		pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, dvconfig);
	}

	/* Ensure busmastering is enabled */
        reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
        pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
		       reg | PCI_COMMAND_MASTER_ENABLE);

	ahd_softc_init(ahd);

	/*
	 * Map the interrupt routines
	 */
	ahd->bus_intr = ahd_pci_intr;

	error = ahd_reset(ahd, /*reinit*/FALSE);
	if (error != 0) {
		ahd_free(ahd);
		return;
	}

	if (pci_intr_map(pa, &ih)) {
		aprint_error("%s: couldn't map interrupt\n", ahd_name(ahd));
		ahd_free(ahd);
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	ahd->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahd_intr, ahd);
	if (ahd->ih == NULL) {
		aprint_error("%s: couldn't establish interrupt",
		       ahd_name(ahd));
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		ahd_free(ahd);
		return;
	}
	if (intrstr != NULL)
		aprint_normal("%s: interrupting at %s\n", ahd_name(ahd),
		       intrstr);

	/* Get the size of the cache */
	ahd->pci_cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
	ahd->pci_cachesize *= 4;

 	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
	/* See if we have a SEEPROM and perform auto-term */
	error = ahd_check_extport(ahd);
	if (error != 0)
		return;

	/* Core initialization */
	error = ahd_init(ahd);
	if (error != 0)
		return;

	/*
	 * Link this softc in with all other ahd instances.
	 */
	ahd_attach(ahd);
}
static void
exyo_attach(device_t parent, device_t self, void *aux)
{
	const struct exyo_locators *l = NULL;
	struct exyo_softc * const sc = &exyo_sc;
	prop_dictionary_t dict = device_properties(self);
	size_t nl = 0;

	sc->sc_dev = self;
	sc->sc_bst = &exynos_bs_tag;
	sc->sc_a4x_bst = &exynos_a4x_bs_tag;
	sc->sc_bsh = exynos_core_bsh;
	sc->sc_dmat = &exynos_bus_dma_tag;
	sc->sc_coherent_dmat = &exynos_coherent_bus_dma_tag;

	const uint16_t product_id = EXYNOS_PRODUCT_ID(exynos_soc_id);
	aprint_naive(": Exynos %x\n", product_id);
	aprint_normal(": Exynos %x\n", product_id);

	/* add sysctl nodes */
	exynos_sysctl_cpufreq_init();

	/* add all children */
#if defined(EXYNOS4)
	if (IS_EXYNOS4_P()) {
		l = exynos4_locinfo.locators;
		nl = exynos4_locinfo.nlocators;
	}
#endif
#if defined(EXYNOS5)
	if (IS_EXYNOS5_P()) {
		l = exynos5_locinfo.locators;
		nl = exynos5_locinfo.nlocators;
	}	
#endif 
	KASSERT(l != NULL);
	KASSERT(nl > 0);

	for (const struct exyo_locators *loc = l; loc < l + nl; loc++) {
		char prop_name[31];
		bool skip;

		if (loc->loc_port == EXYOCF_PORT_DEFAULT) {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s", loc->loc_name);
		} else {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s-%d", loc->loc_name, loc->loc_port);
		}
		if (prop_dictionary_get_bool(dict, prop_name, &skip) && skip)
			continue;

		struct exyo_attach_args exyo = {
			.exyo_loc = *loc,
			.exyo_core_bst = sc->sc_bst,
			.exyo_core_a4x_bst = sc->sc_a4x_bst,
			.exyo_core_bsh = sc->sc_bsh,
			.exyo_dmat = sc->sc_dmat,
			.exyo_coherent_dmat = sc->sc_coherent_dmat,
		};
		cfdata_t cf = config_search_ia(exyo_find,
		    sc->sc_dev, "exyo", &exyo);
		if (cf == NULL) {
#ifdef EXYO_REQUIRED
			if (loc->loc_flags & EXYO_REQUIRED)
				panic("%s: failed to find %s!", __func__,
				    loc->loc_name);
#endif
			if (loc->loc_port == EXYOCF_PORT_DEFAULT) {
				aprint_verbose_dev(self, "%s not found\n",
				    loc->loc_name);
			} else {
				aprint_verbose_dev(self, "%s%d not found\n",
				    loc->loc_name, loc->loc_port);
			}
			continue;
		}
		config_attach(sc->sc_dev, cf, &exyo, exyo_print);
	}
}
void
midi_attach(struct midi_softc *sc)
{
	struct midi_info mi;
	kmutex_t *dummy;
	static int first = 1;

	if (first) {
		mutex_init(&hwif_softc_lock, MUTEX_DEFAULT, IPL_NONE);
		first = 0;
	}

	sc->hw_if->get_locks(sc->hw_hdl, &sc->lock, &dummy);

	callout_init(&sc->xmt_asense_co, CALLOUT_MPSAFE);
	callout_init(&sc->rcv_asense_co, CALLOUT_MPSAFE);
	callout_setfunc(&sc->xmt_asense_co, midi_xmt_asense, sc);
	callout_setfunc(&sc->rcv_asense_co, midi_rcv_asense, sc);

	sc->sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE,
	    midi_softint, sc);

	cv_init(&sc->rchan, "midird");
	cv_init(&sc->wchan, "midiwr");

	sc->dying = 0;
	sc->isopen = 0;

	mutex_enter(&hwif_softc_lock);
	mutex_enter(sc->lock);
	hwif_softc = sc;
	sc->hw_if->getinfo(sc->hw_hdl, &mi);
	hwif_softc = NULL;
	mutex_exit(sc->lock);
	mutex_exit(&hwif_softc_lock);

	sc->props = mi.props;

	if (!(sc->props & MIDI_PROP_NO_OUTPUT)) {
		evcnt_attach_dynamic(&sc->xmt.bytesDiscarded,
			EVCNT_TYPE_MISC, NULL,
			device_xname(sc->dev), "xmt bytes discarded");
		evcnt_attach_dynamic(&sc->xmt.incompleteMessages,
			EVCNT_TYPE_MISC, NULL,
			device_xname(sc->dev), "xmt incomplete msgs");
	}
	if (sc->props & MIDI_PROP_CAN_INPUT) {
		evcnt_attach_dynamic(&sc->rcv.bytesDiscarded,
			EVCNT_TYPE_MISC, NULL,
			device_xname(sc->dev), "rcv bytes discarded");
		evcnt_attach_dynamic(&sc->rcv.incompleteMessages,
			EVCNT_TYPE_MISC, NULL,
			device_xname(sc->dev), "rcv incomplete msgs");
	}
	
	aprint_naive("\n");
	aprint_normal(": %s\n", mi.name);

	if (!pmf_device_register(sc->dev, NULL, NULL))
		aprint_error_dev(sc->dev, "couldn't establish power handler\n"); 
}