Date: Tue, 5 Aug 2014 07:03:17 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r269567 - in head/sys: boot/usb conf dev/usb dev/usb/template modules/usb/template Message-ID: <53e081b5.5c76.4a0ed79e@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Tue Aug 5 07:03:16 2014 New Revision: 269567 URL: http://svnweb.freebsd.org/changeset/base/269567 Log: Add new USB phone descriptor template for USB device side mode. MFC after: 3 days Added: head/sys/dev/usb/template/usb_template_phone.c (contents, props changed) Modified: head/sys/boot/usb/usbcore.mk head/sys/conf/files head/sys/dev/usb/template/usb_template.c head/sys/dev/usb/template/usb_template.h head/sys/dev/usb/usb_ioctl.h head/sys/modules/usb/template/Makefile Modified: head/sys/boot/usb/usbcore.mk ============================================================================== --- head/sys/boot/usb/usbcore.mk Tue Aug 5 06:38:21 2014 (r269566) +++ head/sys/boot/usb/usbcore.mk Tue Aug 5 07:03:16 2014 (r269567) @@ -141,6 +141,7 @@ KSRCS+= usb_template_modem.c KSRCS+= usb_template_mouse.c KSRCS+= usb_template_kbd.c KSRCS+= usb_template_audio.c +KSRCS+= usb_template_phone.c # # USB mass storage support Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Tue Aug 5 06:38:21 2014 (r269566) +++ head/sys/conf/files Tue Aug 5 07:03:16 2014 (r269567) @@ -2514,6 +2514,7 @@ dev/usb/template/usb_template_modem.c op dev/usb/template/usb_template_mouse.c optional usb_template dev/usb/template/usb_template_msc.c optional usb_template dev/usb/template/usb_template_mtp.c optional usb_template +dev/usb/template/usb_template_phone.c optional usb_template # # USB END # Modified: head/sys/dev/usb/template/usb_template.c ============================================================================== --- head/sys/dev/usb/template/usb_template.c Tue Aug 5 06:38:21 2014 (r269566) +++ head/sys/dev/usb/template/usb_template.c Tue Aug 5 07:03:16 2014 (r269567) @@ -135,7 +135,7 @@ usb_make_raw_desc(struct usb_temp_setup /* check if we have got a CDC union descriptor */ - if ((raw[0] >= sizeof(struct usb_cdc_union_descriptor)) && + if ((raw[0] == sizeof(struct usb_cdc_union_descriptor)) && (raw[1] == UDESC_CS_INTERFACE) && (raw[2] == UDESCSUB_CDC_UNION)) { struct usb_cdc_union_descriptor *ud = (void *)dst; @@ -150,7 +150,7 @@ usb_make_raw_desc(struct usb_temp_setup /* check if we have got an interface association descriptor */ - if ((raw[0] >= sizeof(struct usb_interface_assoc_descriptor)) && + if ((raw[0] == sizeof(struct usb_interface_assoc_descriptor)) && (raw[1] == UDESC_IFACE_ASSOC)) { struct usb_interface_assoc_descriptor *iad = (void *)dst; @@ -162,7 +162,7 @@ usb_make_raw_desc(struct usb_temp_setup /* check if we have got a call management descriptor */ - if ((raw[0] >= sizeof(struct usb_cdc_cm_descriptor)) && + if ((raw[0] == sizeof(struct usb_cdc_cm_descriptor)) && (raw[1] == UDESC_CS_INTERFACE) && (raw[2] == UDESCSUB_CDC_CM)) { struct usb_cdc_cm_descriptor *ccd = (void *)dst; @@ -1368,6 +1368,9 @@ usb_temp_setup_by_index(struct usb_devic case USB_TEMP_MOUSE: err = usb_temp_setup(udev, &usb_template_mouse); break; + case USB_TEMP_PHONE: + err = usb_temp_setup(udev, &usb_template_phone); + break; default: return (USB_ERR_INVAL); } Modified: head/sys/dev/usb/template/usb_template.h ============================================================================== --- head/sys/dev/usb/template/usb_template.h Tue Aug 5 06:38:21 2014 (r269566) +++ head/sys/dev/usb/template/usb_template.h Tue Aug 5 07:03:16 2014 (r269567) @@ -105,6 +105,7 @@ extern const struct usb_temp_device_desc extern const struct usb_temp_device_desc usb_template_mouse; extern const struct usb_temp_device_desc usb_template_msc; extern const struct usb_temp_device_desc usb_template_mtp; +extern const struct usb_temp_device_desc usb_template_phone; usb_error_t usb_temp_setup(struct usb_device *, const struct usb_temp_device_desc *); Added: head/sys/dev/usb/template/usb_template_phone.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/usb/template/usb_template_phone.c Tue Aug 5 07:03:16 2014 (r269567) @@ -0,0 +1,419 @@ +/* $FreeBSD$ */ +/*- + * Copyright (c) 2014 Hans Petter Selasky. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * This file contains the USB template for an USB phone device. + */ + +#ifdef USB_GLOBAL_INCLUDE_FILE +#include USB_GLOBAL_INCLUDE_FILE +#else +#include <sys/stdint.h> +#include <sys/stddef.h> +#include <sys/param.h> +#include <sys/queue.h> +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/bus.h> +#include <sys/module.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/condvar.h> +#include <sys/sysctl.h> +#include <sys/sx.h> +#include <sys/unistd.h> +#include <sys/callout.h> +#include <sys/malloc.h> +#include <sys/priv.h> + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include <dev/usb/usb_core.h> +#include <dev/usb/usb_cdc.h> + +#include <dev/usb/template/usb_template.h> +#endif /* USB_GLOBAL_INCLUDE_FILE */ + +enum { + INDEX_PHONE_LANG, + INDEX_PHONE_MIXER, + INDEX_PHONE_RECORD, + INDEX_PHONE_PLAYBACK, + INDEX_PHONE_PRODUCT, + INDEX_PHONE_HID, + INDEX_PHONE_MAX, +}; + +#define STRING_PHONE_PRODUCT \ + "U\0S\0B\0 \0P\0h\0o\0n\0e\0 \0D\0e\0v\0i\0c\0e" + +#define STRING_PHONE_MIXER \ + "M\0i\0x\0e\0r\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e" + +#define STRING_PHONE_RECORD \ + "R\0e\0c\0o\0r\0d\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e" + +#define STRING_PHONE_PLAYBACK \ + "P\0l\0a\0y\0b\0a\0c\0k\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e" + +#define STRING_PHONE_HID \ + "H\0I\0D\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e" + +/* make the real string descriptors */ + +USB_MAKE_STRING_DESC(STRING_PHONE_MIXER, string_phone_mixer); +USB_MAKE_STRING_DESC(STRING_PHONE_RECORD, string_phone_record); +USB_MAKE_STRING_DESC(STRING_PHONE_PLAYBACK, string_phone_playback); +USB_MAKE_STRING_DESC(STRING_PHONE_PRODUCT, string_phone_product); +USB_MAKE_STRING_DESC(STRING_PHONE_HID, string_phone_hid); + +/* prototypes */ + +/* + * Phone Mixer description structures + * + * Some of the phone descriptors were dumped from no longer in + * production Yealink VOIP USB phone adapter: + */ +static uint8_t phone_hid_descriptor[] = { + 0x05, 0x0b, 0x09, 0x01, 0xa1, 0x01, 0x05, 0x09, + 0x19, 0x01, 0x29, 0x3f, 0x15, 0x00, 0x25, 0x01, + 0x75, 0x01, 0x95, 0x80, 0x81, 0x00, 0x05, 0x08, + 0x19, 0x01, 0x29, 0x10, 0x15, 0x00, 0x25, 0x01, + 0x75, 0x01, 0x95, 0x80, 0x91, 0x00, 0xc0 +}; + +static const uint8_t phone_raw_desc_0[] = { + 0x0a, 0x24, 0x01, 0x00, 0x01, 0x4a, 0x00, 0x02, + 0x01, 0x02 +}; + +static const uint8_t phone_raw_desc_1[] = { + 0x0c, 0x24, 0x02, 0x01, 0x01, 0x02, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t phone_raw_desc_2[] = { + 0x0c, 0x24, 0x02, 0x02, 0x01, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t phone_raw_desc_3[] = { + 0x09, 0x24, 0x03, 0x03, 0x01, 0x03, 0x00, 0x06, + 0x00 +}; + +static const uint8_t phone_raw_desc_4[] = { + 0x09, 0x24, 0x03, 0x04, 0x01, 0x01, 0x00, 0x05, + 0x00 +}; + +static const uint8_t phone_raw_desc_5[] = { + 0x0b, 0x24, 0x06, 0x05, 0x01, 0x02, 0x03, 0x00, + 0x03, 0x00, 0x00 +}; + +static const uint8_t phone_raw_desc_6[] = { + 0x0b, 0x24, 0x06, 0x06, 0x02, 0x02, 0x03, 0x00, + 0x03, 0x00, 0x00 +}; + +static const void *phone_raw_iface_0_desc[] = { + phone_raw_desc_0, + phone_raw_desc_1, + phone_raw_desc_2, + phone_raw_desc_3, + phone_raw_desc_4, + phone_raw_desc_5, + phone_raw_desc_6, + NULL, +}; + +static const struct usb_temp_interface_desc phone_iface_0 = { + .ppEndpoints = NULL, /* no endpoints */ + .ppRawDesc = phone_raw_iface_0_desc, + .bInterfaceClass = 1, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .iInterface = INDEX_PHONE_MIXER, +}; + +static const uint8_t phone_raw_desc_20[] = { + 0x07, 0x24, 0x01, 0x04, 0x01, 0x01, 0x00 +}; + +static const uint8_t phone_raw_desc_21[] = { + 0x0b, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x01, + /* 8kHz */ + 0x40, 0x1f, 0x00 +}; + +static const uint8_t phone_raw_desc_22[] = { + 0x07, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00 +}; + +static const void *phone_raw_iface_1_desc[] = { + phone_raw_desc_20, + phone_raw_desc_21, + NULL, +}; + +static const void *phone_raw_ep_1_desc[] = { + phone_raw_desc_22, + NULL, +}; + +static const struct usb_temp_packet_size phone_isoc_mps = { + .mps[USB_SPEED_FULL] = 0x10, + .mps[USB_SPEED_HIGH] = 0x10, +}; + +static const struct usb_temp_interval phone_isoc_interval = { + .bInterval[USB_SPEED_FULL] = 1, /* 1:1 */ + .bInterval[USB_SPEED_HIGH] = 4, /* 1:8 */ +}; + +static const struct usb_temp_endpoint_desc phone_isoc_in_ep = { + .ppRawDesc = phone_raw_ep_1_desc, + .pPacketSize = &phone_isoc_mps, + .pIntervals = &phone_isoc_interval, + .bEndpointAddress = UE_DIR_IN, + .bmAttributes = UE_ISOCHRONOUS, +}; + +static const struct usb_temp_endpoint_desc *phone_iface_1_ep[] = { + &phone_isoc_in_ep, + NULL, +}; + +static const struct usb_temp_interface_desc phone_iface_1_alt_0 = { + .ppEndpoints = NULL, /* no endpoints */ + .ppRawDesc = NULL, /* no raw descriptors */ + .bInterfaceClass = 1, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 0, + .iInterface = INDEX_PHONE_PLAYBACK, +}; + +static const struct usb_temp_interface_desc phone_iface_1_alt_1 = { + .ppEndpoints = phone_iface_1_ep, + .ppRawDesc = phone_raw_iface_1_desc, + .bInterfaceClass = 1, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 0, + .iInterface = INDEX_PHONE_PLAYBACK, + .isAltInterface = 1, /* this is an alternate setting */ +}; + +static const uint8_t phone_raw_desc_30[] = { + 0x07, 0x24, 0x01, 0x02, 0x01, 0x01, 0x00 +}; + +static const uint8_t phone_raw_desc_31[] = { + 0x0b, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x01, + /* 8kHz */ + 0x40, 0x1f, 0x00 +}; + +static const uint8_t phone_raw_desc_32[] = { + 0x07, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00 +}; + +static const void *phone_raw_iface_2_desc[] = { + phone_raw_desc_30, + phone_raw_desc_31, + NULL, +}; + +static const void *phone_raw_ep_2_desc[] = { + phone_raw_desc_32, + NULL, +}; + +static const struct usb_temp_endpoint_desc phone_isoc_out_ep = { + .ppRawDesc = phone_raw_ep_2_desc, + .pPacketSize = &phone_isoc_mps, + .pIntervals = &phone_isoc_interval, + .bEndpointAddress = UE_DIR_OUT, + .bmAttributes = UE_ISOCHRONOUS, +}; + +static const struct usb_temp_endpoint_desc *phone_iface_2_ep[] = { + &phone_isoc_out_ep, + NULL, +}; + +static const struct usb_temp_interface_desc phone_iface_2_alt_0 = { + .ppEndpoints = NULL, /* no endpoints */ + .ppRawDesc = NULL, /* no raw descriptors */ + .bInterfaceClass = 1, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 0, + .iInterface = INDEX_PHONE_RECORD, +}; + +static const struct usb_temp_interface_desc phone_iface_2_alt_1 = { + .ppEndpoints = phone_iface_2_ep, + .ppRawDesc = phone_raw_iface_2_desc, + .bInterfaceClass = 1, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 0, + .iInterface = INDEX_PHONE_RECORD, + .isAltInterface = 1, /* this is an alternate setting */ +}; + +static const uint8_t phone_hid_raw_desc_0[] = { + 0x09, 0x21, 0x00, 0x01, 0x00, 0x01, 0x22, sizeof(phone_hid_descriptor), + 0x00 +}; + +static const void *phone_hid_desc_0[] = { + phone_hid_raw_desc_0, + NULL, +}; + +static const struct usb_temp_packet_size phone_hid_mps = { + .mps[USB_SPEED_FULL] = 0x10, + .mps[USB_SPEED_HIGH] = 0x10, +}; + +static const struct usb_temp_interval phone_hid_interval = { + .bInterval[USB_SPEED_FULL] = 2, /* 2ms */ + .bInterval[USB_SPEED_HIGH] = 2, /* 2ms */ +}; + +static const struct usb_temp_endpoint_desc phone_hid_in_ep = { + .pPacketSize = &phone_hid_mps, + .pIntervals = &phone_hid_interval, + .bEndpointAddress = UE_DIR_IN, + .bmAttributes = UE_INTERRUPT, +}; + +static const struct usb_temp_endpoint_desc *phone_iface_3_ep[] = { + &phone_hid_in_ep, + NULL, +}; + +static const struct usb_temp_interface_desc phone_iface_3 = { + .ppEndpoints = phone_iface_3_ep, + .ppRawDesc = phone_hid_desc_0, + .bInterfaceClass = 3, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = INDEX_PHONE_HID, +}; + +static const struct usb_temp_interface_desc *phone_interfaces[] = { + &phone_iface_0, + &phone_iface_1_alt_0, + &phone_iface_1_alt_1, + &phone_iface_2_alt_0, + &phone_iface_2_alt_1, + &phone_iface_3, + NULL, +}; + +static const struct usb_temp_config_desc phone_config_desc = { + .ppIfaceDesc = phone_interfaces, + .bmAttributes = UC_BUS_POWERED, + .bMaxPower = 25, /* 50 mA */ + .iConfiguration = INDEX_PHONE_PRODUCT, +}; + +static const struct usb_temp_config_desc *phone_configs[] = { + &phone_config_desc, + NULL, +}; + +static usb_temp_get_string_desc_t phone_get_string_desc; +static usb_temp_get_vendor_desc_t phone_get_vendor_desc; + +const struct usb_temp_device_desc usb_template_phone = { + .getStringDesc = &phone_get_string_desc, + .getVendorDesc = &phone_get_vendor_desc, + .ppConfigDesc = phone_configs, + .idVendor = USB_TEMPLATE_VENDOR, + .idProduct = 0xb001, + .bcdDevice = 0x0100, + .bDeviceClass = UDCLASS_IN_INTERFACE, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .iManufacturer = 0, + .iProduct = INDEX_PHONE_PRODUCT, + .iSerialNumber = 0, +}; + +/*------------------------------------------------------------------------* + * phone_get_vendor_desc + * + * Return values: + * NULL: Failure. No such vendor descriptor. + * Else: Success. Pointer to vendor descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +phone_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen) +{ + if ((req->bmRequestType == 0x81) && (req->bRequest == 0x06) && + (req->wValue[0] == 0x00) && (req->wValue[1] == 0x22) && + (req->wIndex[1] == 0) && (req->wIndex[0] == 3 /* iface */)) { + + *plen = sizeof(phone_hid_descriptor); + return (phone_hid_descriptor); + } + return (NULL); +} + +/*------------------------------------------------------------------------* + * phone_get_string_desc + * + * Return values: + * NULL: Failure. No such string. + * Else: Success. Pointer to string descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +phone_get_string_desc(uint16_t lang_id, uint8_t string_index) +{ + static const void *ptr[INDEX_PHONE_MAX] = { + [INDEX_PHONE_LANG] = &usb_string_lang_en, + [INDEX_PHONE_MIXER] = &string_phone_mixer, + [INDEX_PHONE_RECORD] = &string_phone_record, + [INDEX_PHONE_PLAYBACK] = &string_phone_playback, + [INDEX_PHONE_PRODUCT] = &string_phone_product, + [INDEX_PHONE_HID] = &string_phone_hid, + }; + + if (string_index == 0) { + return (&usb_string_lang_en); + } + if (lang_id != 0x0409) { + return (NULL); + } + if (string_index < INDEX_PHONE_MAX) { + return (ptr[string_index]); + } + return (NULL); +} Modified: head/sys/dev/usb/usb_ioctl.h ============================================================================== --- head/sys/dev/usb/usb_ioctl.h Tue Aug 5 06:38:21 2014 (r269566) +++ head/sys/dev/usb/usb_ioctl.h Tue Aug 5 07:03:16 2014 (r269567) @@ -64,6 +64,7 @@ enum { USB_TEMP_AUDIO, /* USB Audio */ USB_TEMP_KBD, /* USB Keyboard */ USB_TEMP_MOUSE, /* USB Mouse */ + USB_TEMP_PHONE, /* USB Phone */ USB_TEMP_MAX, }; Modified: head/sys/modules/usb/template/Makefile ============================================================================== --- head/sys/modules/usb/template/Makefile Tue Aug 5 06:38:21 2014 (r269566) +++ head/sys/modules/usb/template/Makefile Tue Aug 5 07:03:16 2014 (r269567) @@ -38,6 +38,7 @@ SRCS= opt_bus.h opt_usb.h device_if.h bu usb_template_modem.c \ usb_template_mouse.c \ usb_template_msc.c \ - usb_template_mtp.c + usb_template_mtp.c \ + usb_template_phone.c .include <bsd.kmod.mk>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53e081b5.5c76.4a0ed79e>