コード例 #1
0
ファイル: usbdi_util.c プロジェクト: ryoon/netbsd-xhci
usbd_status
usbd_read_report_desc(usbd_interface_handle ifc, void **descp, int *sizep,
		       struct malloc_type * mem)
{
	usb_interface_descriptor_t *id;
	usb_hid_descriptor_t *hid;
	usbd_device_handle dev;
	usbd_status err;

	usbd_interface2device_handle(ifc, &dev);
	id = usbd_get_interface_descriptor(ifc);
	if (id == NULL)
		return (USBD_INVAL);
	hid = usbd_get_hid_descriptor(ifc);
	if (hid == NULL)
		return (USBD_IOERROR);
	*sizep = UGETW(hid->descrs[0].wDescriptorLength);
	*descp = malloc(*sizep, mem, M_NOWAIT);
	if (*descp == NULL)
		return (USBD_NOMEM);
	err = usbd_get_report_descriptor(dev, id->bInterfaceNumber,
					 *sizep, *descp);
	if (err) {
		free(*descp, mem);
		*descp = NULL;
		return (err);
	}
	return (USBD_NORMAL_COMPLETION);
}
コード例 #2
0
ファイル: usbdi_util.c プロジェクト: ryo/netbsd-src
usbd_status
usbd_read_report_desc(struct usbd_interface *ifc, void **descp, int *sizep)
{
	usb_interface_descriptor_t *id;
	usb_hid_descriptor_t *hid;
	struct usbd_device *dev;
	usbd_status err;

	usbd_interface2device_handle(ifc, &dev);
	id = usbd_get_interface_descriptor(ifc);
	if (id == NULL)
		return USBD_INVAL;
	hid = usbd_get_hid_descriptor(ifc);
	if (hid == NULL)
		return USBD_IOERROR;
	*sizep = UGETW(hid->descrs[0].wDescriptorLength);
	*descp = kmem_alloc(*sizep, KM_SLEEP);
	if (*descp == NULL)
		return USBD_NOMEM;
	err = usbd_get_report_descriptor(dev, id->bInterfaceNumber,
					 *sizep, *descp);
	if (err) {
		kmem_free(*descp, *sizep);
		*descp = NULL;
		return err;
	}
	return USBD_NORMAL_COMPLETION;
}
コード例 #3
0
ファイル: ukbd.c プロジェクト: repos-holder/openbsd-patches
void
ukbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct ukbd_softc *sc = (struct ukbd_softc *)self;
	struct usb_attach_arg *uaa = aux;
	struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
	usb_hid_descriptor_t *hid;
	u_int32_t qflags;
	const char *parseerr;
	kbd_t layout = (kbd_t)-1;
	struct wskbddev_attach_args a;

	sc->sc_hdev.sc_intr = ukbd_intr;
	sc->sc_hdev.sc_parent = uha->parent;
	sc->sc_hdev.sc_report_id = uha->reportid;

	parseerr = ukbd_parse_desc(sc);
	if (parseerr != NULL) {
		printf("\n%s: attach failed, %s\n",
		       sc->sc_hdev.sc_dev.dv_xname, parseerr);
		return;
	}

	hid = usbd_get_hid_descriptor(uha->uaa->iface);

#ifdef DIAGNOSTIC
	printf(": %d modifier keys, %d key codes",
	    sc->sc_nmod, sc->sc_nkeycode);
#endif

	qflags = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
	sc->sc_debounce = (qflags & UQ_SPUR_BUT_UP) != 0;

	/*
	 * Remember if we're the console keyboard.
	 *
	 * XXX This always picks the first keyboard on the
	 * first USB bus, but what else can we really do?
	 */
	if ((sc->sc_console_keyboard = ukbd_is_console) != 0) {
		/* Don't let any other keyboard have it. */
		ukbd_is_console = 0;
	}

	if (uha->uaa->vendor == USB_VENDOR_TOPRE &&
	    uha->uaa->product == USB_PRODUCT_TOPRE_HHKB) {
		/* ignore country code on purpose */
	} else {
		if (hid->bCountryCode <= HCC_MAX)
			layout = ukbd_countrylayout[hid->bCountryCode];
#ifdef DIAGNOSTIC
		if (hid->bCountryCode != 0)
			printf(", country code %d", hid->bCountryCode);
#endif
	}
	if (layout == (kbd_t)-1) {
#ifdef UKBD_LAYOUT
		layout = UKBD_LAYOUT;
#else
		layout = KB_US;
#endif
	}
	ukbd_keymapdata.layout = layout;

	printf("\n");

	if (sc->sc_console_keyboard) {
		DPRINTF(("ukbd_attach: console keyboard sc=%p\n", sc));
		wskbd_cnattach(&ukbd_consops, sc, &ukbd_keymapdata);
		ukbd_enable(sc, 1);
	}

	a.console = sc->sc_console_keyboard;

	a.keymap = &ukbd_keymapdata;

	a.accessops = &ukbd_accessops;
	a.accesscookie = sc;

#ifdef WSDISPLAY_COMPAT_RAWKBD
	timeout_set(&sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc);
#endif
	timeout_set(&sc->sc_delay, ukbd_delayed_decode, sc);

	/* Flash the leds; no real purpose, just shows we're alive. */
	ukbd_set_leds(sc, WSKBD_LED_SCROLL | WSKBD_LED_NUM | WSKBD_LED_CAPS);
	usbd_delay_ms(uha->parent->sc_udev, 400);
	ukbd_set_leds(sc, 0);

	sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
}
コード例 #4
0
ファイル: uhidev.c プロジェクト: ajinkya93/OpenBSD
void
uhidev_attach(struct device *parent, struct device *self, void *aux)
{
	struct uhidev_softc *sc = (struct uhidev_softc *)self;
	struct usb_attach_arg *uaa = aux;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	struct uhidev_attach_arg uha;
	int size, nrepid, repid, repsz;
	int i, repsizes[256];
	void *desc = NULL;
	struct device *dev;

	sc->sc_udev = uaa->device;
	sc->sc_iface = uaa->iface;
	sc->sc_ifaceno = uaa->ifaceno;
	id = usbd_get_interface_descriptor(sc->sc_iface);

	usbd_set_idle(sc->sc_udev, sc->sc_ifaceno, 0, 0);

	sc->sc_iep_addr = sc->sc_oep_addr = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			printf("%s: could not read endpoint descriptor\n",
			    DEVNAME(sc));
			return;
		}

		DPRINTFN(10,("uhidev_attach: bLength=%d bDescriptorType=%d "
		    "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
		    " bInterval=%d\n",
		    ed->bLength, ed->bDescriptorType,
		    ed->bEndpointAddress & UE_ADDR,
		    UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
		    ed->bmAttributes & UE_XFERTYPE,
		    UGETW(ed->wMaxPacketSize), ed->bInterval));

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
			sc->sc_iep_addr = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
			sc->sc_oep_addr = ed->bEndpointAddress;
		} else {
			printf("%s: unexpected endpoint\n", DEVNAME(sc));
			return;
		}
	}

	/*
	 * Check that we found an input interrupt endpoint.
	 * The output interrupt endpoint is optional
	 */
	if (sc->sc_iep_addr == -1) {
		printf("%s: no input interrupt endpoint\n", DEVNAME(sc));
		return;
	}

#ifndef SMALL_KERNEL
	if (uhidev_use_rdesc(sc, id, uaa->vendor, uaa->product, &desc, &size))
		return;
#endif /* !SMALL_KERNEL */

	if (desc == NULL) {
		struct usb_hid_descriptor *hid;

		hid = usbd_get_hid_descriptor(sc->sc_udev, id);
		if (hid == NULL) {
			printf("%s: no HID descriptor\n", DEVNAME(sc));
			return;
		}
		size = UGETW(hid->descrs[0].wDescriptorLength);
		desc = malloc(size, M_USBDEV, M_NOWAIT);
		if (desc == NULL) {
			printf("%s: no memory\n", DEVNAME(sc));
			return;
		}
		if (usbd_get_report_descriptor(sc->sc_udev, sc->sc_ifaceno,
		    desc, size)) {
			printf("%s: no report descriptor\n", DEVNAME(sc));
			free(desc, M_USBDEV, 0);
			return;
		}
	}

	sc->sc_repdesc = desc;
	sc->sc_repdesc_size = size;

	nrepid = uhidev_maxrepid(desc, size);
	if (nrepid < 0)
		return;
	printf("%s: iclass %d/%d", DEVNAME(sc), id->bInterfaceClass,
	    id->bInterfaceSubClass);
	if (nrepid > 0)
		printf(", %d report id%s", nrepid, nrepid > 1 ? "s" : "");
	printf("\n");
	nrepid++;
	sc->sc_subdevs = mallocarray(nrepid, sizeof(struct uhidev *),
	    M_USBDEV, M_NOWAIT | M_ZERO);
	if (sc->sc_subdevs == NULL) {
		printf("%s: no memory\n", DEVNAME(sc));
		return;
	}
	sc->sc_nrepid = nrepid;
	sc->sc_isize = 0;

	for (repid = 0; repid < nrepid; repid++) {
		repsz = hid_report_size(desc, size, hid_input, repid);
		DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz));
		repsizes[repid] = repsz;
		if (repsz > sc->sc_isize)
			sc->sc_isize = repsz;
	}
	sc->sc_isize += (nrepid != 1);	/* one byte for the report ID */
	DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));

	uha.uaa = uaa;
	uha.parent = sc;
	uha.reportid = UHIDEV_CLAIM_ALLREPORTID;

	/* Look for a driver claiming all report IDs first. */
	dev = config_found_sm(self, &uha, NULL, uhidevsubmatch);
	if (dev != NULL) {
		for (repid = 0; repid < nrepid; repid++)
			sc->sc_subdevs[repid] = (struct uhidev *)dev;
		return;
	}

	for (repid = 0; repid < nrepid; repid++) {
		DPRINTF(("%s: try repid=%d\n", __func__, repid));
		if (hid_report_size(desc, size, hid_input, repid) == 0 &&
		    hid_report_size(desc, size, hid_output, repid) == 0 &&
		    hid_report_size(desc, size, hid_feature, repid) == 0)
			continue;

		uha.reportid = repid;
		dev = config_found_sm(self, &uha, uhidevprint, uhidevsubmatch);
		sc->sc_subdevs[repid] = (struct uhidev *)dev;
	}
}
コード例 #5
0
ファイル: ukbd.c プロジェクト: appleorange1/bitrig
void
ukbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct ukbd_softc *sc = (struct ukbd_softc *)self;
	struct hidkbd *kbd = &sc->sc_kbd;
	struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
	struct usb_hid_descriptor *hid;
	u_int32_t qflags;
	int dlen, repid;
	void *desc;
	kbd_t layout = (kbd_t)-1;

	sc->sc_hdev.sc_intr = ukbd_intr;
	sc->sc_hdev.sc_parent = uha->parent;
	sc->sc_hdev.sc_udev = uha->uaa->device;
	sc->sc_hdev.sc_report_id = uha->reportid;

	uhidev_get_report_desc(uha->parent, &desc, &dlen);
	repid = uha->reportid;
	sc->sc_hdev.sc_isize = hid_report_size(desc, dlen, hid_input, repid);
	sc->sc_hdev.sc_osize = hid_report_size(desc, dlen, hid_output, repid);
	sc->sc_hdev.sc_fsize = hid_report_size(desc, dlen, hid_feature, repid);

	qflags = usbd_get_quirks(sc->sc_hdev.sc_udev)->uq_flags;
	if (hidkbd_attach(self, kbd, 1, qflags, repid, desc, dlen) != 0)
		return;

	if (uha->uaa->vendor == USB_VENDOR_APPLE) {
		int iso = 0;

		if ((uha->uaa->product == USB_PRODUCT_APPLE_FOUNTAIN_ISO) ||
 		    (uha->uaa->product == USB_PRODUCT_APPLE_GEYSER_ISO))
 		    	iso = 1;

		if (hid_locate(desc, dlen, HID_USAGE2(HUP_APPLE, HUG_FN_KEY),
		    uha->reportid, hid_input, &sc->sc_apple_fn, &qflags)) {
			if (qflags & HIO_VARIABLE) {
				if (iso)
					sc->sc_munge = ukbd_apple_iso_munge;
				else
					sc->sc_munge = ukbd_apple_munge;
			}
		}
	}

	if (uha->uaa->vendor == USB_VENDOR_TOPRE &&
	    uha->uaa->product == USB_PRODUCT_TOPRE_HHKB) {
		/* ignore country code on purpose */
	} else {
		hid = usbd_get_hid_descriptor(uha->uaa->iface);

		if (hid->bCountryCode <= HCC_MAX)
			layout = ukbd_countrylayout[hid->bCountryCode];
#ifdef DIAGNOSTIC
		if (hid->bCountryCode != 0)
			printf(", country code %d", hid->bCountryCode);
#endif
	}
	if (layout == (kbd_t)-1) {
#ifdef UKBD_LAYOUT
		layout = UKBD_LAYOUT;
#else
		layout = KB_US | KB_DEFAULT;
#endif
	}

	printf("\n");

#ifdef __loongson__
	if (uha->uaa->vendor == USB_VENDOR_CYPRESS &&
	    uha->uaa->product == USB_PRODUCT_CYPRESS_LPRDK)
		sc->sc_munge = ukbd_gdium_munge;
#endif

	if (kbd->sc_console_keyboard) {
		extern struct wskbd_mapdata ukbd_keymapdata;

		DPRINTF(("ukbd_attach: console keyboard sc=%p\n", sc));
		ukbd_keymapdata.layout = layout;
		wskbd_cnattach(&ukbd_consops, sc, &ukbd_keymapdata);
		ukbd_enable(sc, 1);
	}

	/* Flash the leds; no real purpose, just shows we're alive. */
	ukbd_set_leds(sc, WSKBD_LED_SCROLL | WSKBD_LED_NUM |
		          WSKBD_LED_CAPS | WSKBD_LED_COMPOSE);
	usbd_delay_ms(sc->sc_hdev.sc_udev, 400);
	ukbd_set_leds(sc, 0);

	hidkbd_attach_wskbd(kbd, layout, &ukbd_accessops);
}