Add sysctls to control device side USB identifiers. This makes it
possible to change string and numeric vendor and product identifiers, as well as anything else there might be to change for a particular device side template, eg the MAC address. Reviewed by: hselasky@ MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D13920
This commit is contained in:
parent
1c5196c3ed
commit
8e06491a4e
@ -61,11 +61,12 @@ descriptors.
|
||||
.
|
||||
USB templates are selected using the
|
||||
.Va hw.usb.template
|
||||
sysctl and tunable.
|
||||
.
|
||||
The
|
||||
.Va hw.usb.template
|
||||
value can be changed at any time, but will not
|
||||
sysctl and tunable,
|
||||
or by using the
|
||||
.Xr usbconfig 8
|
||||
.Cm set_template
|
||||
subcommand.
|
||||
The sysctl values can be changed at any time, but will not
|
||||
have any effect until the USB device has been re-enumerated.
|
||||
.
|
||||
Available templates are:
|
||||
@ -83,10 +84,32 @@ Available templates are:
|
||||
.It Dv 9 Ta USB MIDI
|
||||
.El
|
||||
.
|
||||
.Sh SYSCTL VARIABLES
|
||||
The following variables are available as both
|
||||
.Xr sysctl 8
|
||||
variables and
|
||||
.Xr loader 8
|
||||
tunables:
|
||||
.Bl -tag -width indent
|
||||
.It Va hw.usb.template
|
||||
Currently selected template.
|
||||
.It Va hw.usb.templates.N
|
||||
Configuration for template number
|
||||
.Va N .
|
||||
.It Va hw.usb.templates.N.vendor_id
|
||||
16-bit vendor identifier (VID), usually assigned by USB-IF.
|
||||
.It Va hw.usb.templates.N.product_id
|
||||
16-bit product identifier (PID).
|
||||
.It Va hw.usb.templates.N.manufacturer
|
||||
String containing human-readable manufacturer name.
|
||||
.It Va hw.usb.templates.N.product
|
||||
String containing human-readable product name.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr cfumass 4 ,
|
||||
.Xr usb 4 ,
|
||||
.Xr usfs 4
|
||||
.Xr usfs 4 ,
|
||||
.Xr usbconfig 8
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <dev/usb/usb_busdma.h>
|
||||
#include <dev/usb/usb_process.h>
|
||||
#include <dev/usb/usb_device.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#define USB_DEBUG_VAR usb_debug
|
||||
#include <dev/usb/usb_debug.h>
|
||||
@ -75,6 +76,9 @@
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
|
||||
SYSCTL_NODE(_hw_usb, OID_AUTO, templates, CTLFLAG_RW, 0,
|
||||
"USB device side templates");
|
||||
|
||||
MODULE_DEPEND(usb_template, usb, 1, 1, 1);
|
||||
MODULE_VERSION(usb_template, 1);
|
||||
|
||||
@ -113,6 +117,50 @@ static usb_error_t usb_temp_setup_by_index(struct usb_device *,
|
||||
uint16_t index);
|
||||
static void usb_temp_init(void *);
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb_decode_str_desc
|
||||
*
|
||||
* Helper function to decode string descriptors into a C string.
|
||||
*------------------------------------------------------------------------*/
|
||||
void
|
||||
usb_decode_str_desc(struct usb_string_descriptor *sd, char *buf, size_t buflen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < buflen - 1 && i < sd->bLength / 2; i++)
|
||||
buf[i] = UGETW(sd->bString[i]);
|
||||
|
||||
buf[i] = '\0';
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb_temp_sysctl
|
||||
*
|
||||
* Callback for SYSCTL_PROC(9), to set and retrieve template string
|
||||
* descriptors.
|
||||
*------------------------------------------------------------------------*/
|
||||
int
|
||||
usb_temp_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
char buf[128];
|
||||
struct usb_string_descriptor *sd = arg1;
|
||||
size_t len, sdlen = arg2;
|
||||
int error;
|
||||
|
||||
usb_decode_str_desc(sd, buf, sizeof(buf));
|
||||
|
||||
error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
return (error);
|
||||
|
||||
len = usb_make_str_desc(sd, sdlen, buf);
|
||||
if (len == 0)
|
||||
return (EINVAL);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb_make_raw_desc
|
||||
*
|
||||
|
@ -100,19 +100,25 @@ struct usb_temp_data {
|
||||
|
||||
/* prototypes */
|
||||
|
||||
extern const struct usb_temp_device_desc usb_template_audio;
|
||||
extern const struct usb_temp_device_desc usb_template_cdce;
|
||||
extern const struct usb_temp_device_desc usb_template_kbd;
|
||||
extern const struct usb_temp_device_desc usb_template_modem;
|
||||
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;
|
||||
extern const struct usb_temp_device_desc usb_template_serialnet;
|
||||
extern const struct usb_temp_device_desc usb_template_midi;
|
||||
extern struct usb_temp_device_desc usb_template_audio;
|
||||
extern struct usb_temp_device_desc usb_template_cdce;
|
||||
extern struct usb_temp_device_desc usb_template_kbd;
|
||||
extern struct usb_temp_device_desc usb_template_modem;
|
||||
extern struct usb_temp_device_desc usb_template_mouse;
|
||||
extern struct usb_temp_device_desc usb_template_msc;
|
||||
extern struct usb_temp_device_desc usb_template_mtp;
|
||||
extern struct usb_temp_device_desc usb_template_phone;
|
||||
extern struct usb_temp_device_desc usb_template_serialnet;
|
||||
extern struct usb_temp_device_desc usb_template_midi;
|
||||
|
||||
|
||||
void usb_decode_str_desc(struct usb_string_descriptor *sd,
|
||||
char *buf, size_t buflen);
|
||||
usb_error_t usb_temp_setup(struct usb_device *,
|
||||
const struct usb_temp_device_desc *);
|
||||
void usb_temp_unsetup(struct usb_device *);
|
||||
void usb_temp_unsetup(struct usb_device *);
|
||||
int usb_temp_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
|
||||
SYSCTL_DECL(_hw_usb_templates);
|
||||
|
||||
#endif /* _USB_TEMPLATE_H_ */
|
||||
|
@ -2,7 +2,12 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
|
||||
* Copyright (c) 2010 Hans Petter Selasky
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -56,38 +61,32 @@
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_cdc.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
|
||||
enum {
|
||||
INDEX_AUDIO_LANG,
|
||||
INDEX_AUDIO_MIXER,
|
||||
INDEX_AUDIO_RECORD,
|
||||
INDEX_AUDIO_PLAYBACK,
|
||||
INDEX_AUDIO_PRODUCT,
|
||||
INDEX_AUDIO_MAX,
|
||||
AUDIO_LANG_INDEX,
|
||||
AUDIO_MIXER_INDEX,
|
||||
AUDIO_RECORD_INDEX,
|
||||
AUDIO_PLAYBACK_INDEX,
|
||||
AUDIO_PRODUCT_INDEX,
|
||||
AUDIO_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_AUDIO_PRODUCT \
|
||||
"A\0u\0d\0i\0o\0 \0T\0e\0s\0t\0 \0D\0e\0v\0i\0c\0e"
|
||||
#define AUDIO_DEFAULT_PRODUCT "Audio Test Device"
|
||||
#define AUDIO_DEFAULT_MIXER "Mixer interface"
|
||||
#define AUDIO_DEFAULT_RECORD "Record interface"
|
||||
#define AUDIO_DEFAULT_PLAYBACK "Playback interface"
|
||||
|
||||
#define STRING_AUDIO_MIXER \
|
||||
"M\0i\0x\0e\0r\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
static struct usb_string_descriptor audio_mixer;
|
||||
static struct usb_string_descriptor audio_record;
|
||||
static struct usb_string_descriptor audio_playback;
|
||||
static struct usb_string_descriptor audio_product;
|
||||
|
||||
#define STRING_AUDIO_RECORD \
|
||||
"R\0e\0c\0o\0r\0d\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
|
||||
#define STRING_AUDIO_PLAYBACK \
|
||||
"P\0l\0a\0y\0b\0a\0c\0k\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_AUDIO_MIXER, string_audio_mixer);
|
||||
USB_MAKE_STRING_DESC(STRING_AUDIO_RECORD, string_audio_record);
|
||||
USB_MAKE_STRING_DESC(STRING_AUDIO_PLAYBACK, string_audio_playback);
|
||||
USB_MAKE_STRING_DESC(STRING_AUDIO_PRODUCT, string_audio_product);
|
||||
static struct sysctl_ctx_list audio_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -204,7 +203,7 @@ static const struct usb_temp_interface_desc audio_iface_0 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_AUDIO_MIXER,
|
||||
.iInterface = AUDIO_MIXER_INDEX,
|
||||
};
|
||||
|
||||
static const uint8_t audio_raw_desc_20[] = {
|
||||
@ -262,7 +261,7 @@ static const struct usb_temp_interface_desc audio_iface_1_alt_0 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_AUDIO_PLAYBACK,
|
||||
.iInterface = AUDIO_PLAYBACK_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc audio_iface_1_alt_1 = {
|
||||
@ -271,7 +270,7 @@ static const struct usb_temp_interface_desc audio_iface_1_alt_1 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_AUDIO_PLAYBACK,
|
||||
.iInterface = AUDIO_PLAYBACK_INDEX,
|
||||
.isAltInterface = 1, /* this is an alternate setting */
|
||||
};
|
||||
|
||||
@ -320,7 +319,7 @@ static const struct usb_temp_interface_desc audio_iface_2_alt_0 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_AUDIO_RECORD,
|
||||
.iInterface = AUDIO_RECORD_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc audio_iface_2_alt_1 = {
|
||||
@ -329,7 +328,7 @@ static const struct usb_temp_interface_desc audio_iface_2_alt_1 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_AUDIO_RECORD,
|
||||
.iInterface = AUDIO_RECORD_INDEX,
|
||||
.isAltInterface = 1, /* this is an alternate setting */
|
||||
};
|
||||
|
||||
@ -346,7 +345,7 @@ static const struct usb_temp_config_desc audio_config_desc = {
|
||||
.ppIfaceDesc = audio_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = INDEX_AUDIO_PRODUCT,
|
||||
.iConfiguration = AUDIO_PRODUCT_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *audio_configs[] = {
|
||||
@ -356,7 +355,7 @@ static const struct usb_temp_config_desc *audio_configs[] = {
|
||||
|
||||
static usb_temp_get_string_desc_t audio_get_string_desc;
|
||||
|
||||
const struct usb_temp_device_desc usb_template_audio = {
|
||||
struct usb_temp_device_desc usb_template_audio = {
|
||||
.getStringDesc = &audio_get_string_desc,
|
||||
.ppConfigDesc = audio_configs,
|
||||
.idVendor = USB_TEMPLATE_VENDOR,
|
||||
@ -365,9 +364,7 @@ const struct usb_temp_device_desc usb_template_audio = {
|
||||
.bDeviceClass = UDCLASS_COMM,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = 0,
|
||||
.iProduct = INDEX_AUDIO_PRODUCT,
|
||||
.iSerialNumber = 0,
|
||||
.iProduct = AUDIO_PRODUCT_INDEX,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -380,12 +377,12 @@ const struct usb_temp_device_desc usb_template_audio = {
|
||||
static const void *
|
||||
audio_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[INDEX_AUDIO_MAX] = {
|
||||
[INDEX_AUDIO_LANG] = &usb_string_lang_en,
|
||||
[INDEX_AUDIO_MIXER] = &string_audio_mixer,
|
||||
[INDEX_AUDIO_RECORD] = &string_audio_record,
|
||||
[INDEX_AUDIO_PLAYBACK] = &string_audio_playback,
|
||||
[INDEX_AUDIO_PRODUCT] = &string_audio_product,
|
||||
static const void *ptr[AUDIO_MAX_INDEX] = {
|
||||
[AUDIO_LANG_INDEX] = &usb_string_lang_en,
|
||||
[AUDIO_MIXER_INDEX] = &audio_mixer,
|
||||
[AUDIO_RECORD_INDEX] = &audio_record,
|
||||
[AUDIO_PLAYBACK_INDEX] = &audio_playback,
|
||||
[AUDIO_PRODUCT_INDEX] = &audio_product,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -394,8 +391,66 @@ audio_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < INDEX_AUDIO_MAX) {
|
||||
if (string_index < AUDIO_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
audio_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&audio_mixer, sizeof(audio_mixer),
|
||||
AUDIO_DEFAULT_MIXER);
|
||||
usb_make_str_desc(&audio_record, sizeof(audio_record),
|
||||
AUDIO_DEFAULT_RECORD);
|
||||
usb_make_str_desc(&audio_playback, sizeof(audio_playback),
|
||||
AUDIO_DEFAULT_PLAYBACK);
|
||||
usb_make_str_desc(&audio_product, sizeof(audio_product),
|
||||
AUDIO_DEFAULT_PRODUCT);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_AUDIO);
|
||||
sysctl_ctx_init(&audio_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&audio_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB Audio Interface device side template");
|
||||
SYSCTL_ADD_U16(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN, &usb_template_audio.idVendor,
|
||||
1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN, &usb_template_audio.idProduct,
|
||||
1, "Product identifier");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"mixer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&audio_mixer, sizeof(audio_mixer), usb_temp_sysctl,
|
||||
"A", "Mixer interface string");
|
||||
SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"record", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&audio_record, sizeof(audio_record), usb_temp_sysctl,
|
||||
"A", "Record interface string");
|
||||
SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"playback", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&audio_playback, sizeof(audio_playback), usb_temp_sysctl,
|
||||
"A", "Playback interface string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&audio_product, sizeof(audio_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
}
|
||||
|
||||
static void
|
||||
audio_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&audio_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(audio_init, SI_SUB_LOCK, SI_ORDER_FIRST, audio_init, NULL);
|
||||
SYSUNINIT(audio_init, SI_SUB_LOCK, SI_ORDER_FIRST, audio_uninit, NULL);
|
||||
|
@ -3,8 +3,12 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2007 Hans Petter Selasky <hselasky@FreeBSD.org>
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -57,54 +61,41 @@
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_cdc.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
|
||||
enum {
|
||||
STRING_LANG_INDEX,
|
||||
STRING_MAC_INDEX,
|
||||
STRING_ETH_CONTROL_INDEX,
|
||||
STRING_ETH_DATA_INDEX,
|
||||
STRING_ETH_CONFIG_INDEX,
|
||||
STRING_ETH_VENDOR_INDEX,
|
||||
STRING_ETH_PRODUCT_INDEX,
|
||||
STRING_ETH_SERIAL_INDEX,
|
||||
STRING_ETH_MAX,
|
||||
ETH_LANG_INDEX,
|
||||
ETH_MAC_INDEX,
|
||||
ETH_CONTROL_INDEX,
|
||||
ETH_DATA_INDEX,
|
||||
ETH_CONFIGURATION_INDEX,
|
||||
ETH_MANUFACTURER_INDEX,
|
||||
ETH_PRODUCT_INDEX,
|
||||
ETH_SERIAL_NUMBER_INDEX,
|
||||
ETH_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_MAC \
|
||||
"2\0A\0002\0003\0004\0005\0006\0007\08\09\0A\0B"
|
||||
#define ETH_DEFAULT_MAC "2A02030405060789AB"
|
||||
#define ETH_DEFAULT_CONTROL "USB Ethernet Comm Interface"
|
||||
#define ETH_DEFAULT_DATA "USB Ethernet Data Interface"
|
||||
#define ETH_DEFAULT_CONFIG "Default Config"
|
||||
#define ETH_DEFAULT_MANUFACTURER "FreeBSD foundation"
|
||||
#define ETH_DEFAULT_PRODUCT "USB Ethernet Adapter"
|
||||
#define ETH_DEFAULT_SERIAL_NUMBER "December 2007"
|
||||
|
||||
#define STRING_ETH_CONTROL \
|
||||
"U\0S\0B\0 \0E\0t\0h\0e\0r\0n\0e\0t\0 " \
|
||||
"\0C\0o\0m\0m\0 \0I\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
static struct usb_string_descriptor eth_mac;
|
||||
static struct usb_string_descriptor eth_control;
|
||||
static struct usb_string_descriptor eth_data;
|
||||
static struct usb_string_descriptor eth_configuration;
|
||||
static struct usb_string_descriptor eth_manufacturer;
|
||||
static struct usb_string_descriptor eth_product;
|
||||
static struct usb_string_descriptor eth_serial_number;
|
||||
|
||||
#define STRING_ETH_DATA \
|
||||
"U\0S\0B\0 \0E\0t\0h\0e\0r\0n\0e\0t\0 \0D\0a\0t\0a\0 " \
|
||||
"\0I\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
|
||||
#define STRING_ETH_CONFIG \
|
||||
"D\0e\0f\0a\0u\0l\0t\0 \0c\0o\0n\0f\0i\0g"
|
||||
|
||||
#define STRING_ETH_VENDOR \
|
||||
"F\0r\0e\0e\0B\0S\0D\0 \0f\0o\0u\0n\0d\0a\0t\0i\0o\0n"
|
||||
|
||||
#define STRING_ETH_PRODUCT \
|
||||
"U\0S\0B\0 \0E\0t\0h\0e\0r\0n\0e\0t\0 \0A\0d\0a\0p\0t\0e\0r"
|
||||
|
||||
#define STRING_ETH_SERIAL \
|
||||
"D\0e\0c\0e\0m\0b\0e\0r\0 \0002\0000\0000\0007"
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_MAC, string_mac);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_CONTROL, string_eth_control);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_DATA, string_eth_data);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_CONFIG, string_eth_config);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_VENDOR, string_eth_vendor);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_PRODUCT, string_eth_product);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_SERIAL, string_eth_serial);
|
||||
static struct sysctl_ctx_list eth_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -130,7 +121,7 @@ static const struct usb_cdc_ethernet_descriptor eth_enf_desc = {
|
||||
.bLength = sizeof(eth_enf_desc),
|
||||
.bDescriptorType = UDESC_CS_INTERFACE,
|
||||
.bDescriptorSubtype = UDESCSUB_CDC_ENF,
|
||||
.iMacAddress = STRING_MAC_INDEX,
|
||||
.iMacAddress = ETH_MAC_INDEX,
|
||||
.bmEthernetStatistics = {0, 0, 0, 0},
|
||||
.wMaxSegmentSize = {0xEA, 0x05},/* 1514 bytes */
|
||||
.wNumberMCFilters = {0, 0},
|
||||
@ -191,7 +182,7 @@ static const struct usb_temp_interface_desc eth_control_interface = {
|
||||
.bInterfaceClass = UICLASS_CDC,
|
||||
.bInterfaceSubClass = UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = STRING_ETH_CONTROL_INDEX,
|
||||
.iInterface = ETH_CONTROL_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_endpoint_desc *eth_data_endpoints[] = {
|
||||
@ -205,7 +196,7 @@ static const struct usb_temp_interface_desc eth_data_null_interface = {
|
||||
.bInterfaceClass = UICLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = STRING_ETH_DATA_INDEX,
|
||||
.iInterface = ETH_DATA_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc eth_data_interface = {
|
||||
@ -213,7 +204,7 @@ static const struct usb_temp_interface_desc eth_data_interface = {
|
||||
.bInterfaceClass = UICLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = UISUBCLASS_DATA,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = STRING_ETH_DATA_INDEX,
|
||||
.iInterface = ETH_DATA_INDEX,
|
||||
.isAltInterface = 1, /* this is an alternate setting */
|
||||
};
|
||||
|
||||
@ -228,7 +219,7 @@ static const struct usb_temp_config_desc eth_config_desc = {
|
||||
.ppIfaceDesc = eth_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = STRING_ETH_CONFIG_INDEX,
|
||||
.iConfiguration = ETH_CONFIGURATION_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *eth_configs[] = {
|
||||
@ -236,7 +227,7 @@ static const struct usb_temp_config_desc *eth_configs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
const struct usb_temp_device_desc usb_template_cdce = {
|
||||
struct usb_temp_device_desc usb_template_cdce = {
|
||||
.getStringDesc = ð_get_string_desc,
|
||||
.ppConfigDesc = eth_configs,
|
||||
.idVendor = USB_TEMPLATE_VENDOR,
|
||||
@ -245,9 +236,9 @@ const struct usb_temp_device_desc usb_template_cdce = {
|
||||
.bDeviceClass = UDCLASS_COMM,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = STRING_ETH_VENDOR_INDEX,
|
||||
.iProduct = STRING_ETH_PRODUCT_INDEX,
|
||||
.iSerialNumber = STRING_ETH_SERIAL_INDEX,
|
||||
.iManufacturer = ETH_MANUFACTURER_INDEX,
|
||||
.iProduct = ETH_PRODUCT_INDEX,
|
||||
.iSerialNumber = ETH_SERIAL_NUMBER_INDEX,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -260,15 +251,15 @@ const struct usb_temp_device_desc usb_template_cdce = {
|
||||
static const void *
|
||||
eth_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[STRING_ETH_MAX] = {
|
||||
[STRING_LANG_INDEX] = &usb_string_lang_en,
|
||||
[STRING_MAC_INDEX] = &string_mac,
|
||||
[STRING_ETH_CONTROL_INDEX] = &string_eth_control,
|
||||
[STRING_ETH_DATA_INDEX] = &string_eth_data,
|
||||
[STRING_ETH_CONFIG_INDEX] = &string_eth_config,
|
||||
[STRING_ETH_VENDOR_INDEX] = &string_eth_vendor,
|
||||
[STRING_ETH_PRODUCT_INDEX] = &string_eth_product,
|
||||
[STRING_ETH_SERIAL_INDEX] = &string_eth_serial,
|
||||
static const void *ptr[ETH_MAX_INDEX] = {
|
||||
[ETH_LANG_INDEX] = &usb_string_lang_en,
|
||||
[ETH_MAC_INDEX] = ð_mac,
|
||||
[ETH_CONTROL_INDEX] = ð_control,
|
||||
[ETH_DATA_INDEX] = ð_data,
|
||||
[ETH_CONFIGURATION_INDEX] = ð_configuration,
|
||||
[ETH_MANUFACTURER_INDEX] = ð_manufacturer,
|
||||
[ETH_PRODUCT_INDEX] = ð_product,
|
||||
[ETH_SERIAL_NUMBER_INDEX] = ð_serial_number,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -277,8 +268,84 @@ eth_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < STRING_ETH_MAX) {
|
||||
if (string_index < ETH_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
eth_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(ð_mac, sizeof(eth_mac),
|
||||
ETH_DEFAULT_MAC);
|
||||
usb_make_str_desc(ð_control, sizeof(eth_control),
|
||||
ETH_DEFAULT_CONTROL);
|
||||
usb_make_str_desc(ð_data, sizeof(eth_data),
|
||||
ETH_DEFAULT_DATA);
|
||||
usb_make_str_desc(ð_configuration, sizeof(eth_configuration),
|
||||
ETH_DEFAULT_CONFIG);
|
||||
usb_make_str_desc(ð_manufacturer, sizeof(eth_manufacturer),
|
||||
ETH_DEFAULT_MANUFACTURER);
|
||||
usb_make_str_desc(ð_product, sizeof(eth_product),
|
||||
ETH_DEFAULT_PRODUCT);
|
||||
usb_make_str_desc(ð_serial_number, sizeof(eth_serial_number),
|
||||
ETH_DEFAULT_SERIAL_NUMBER);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_CDCE);
|
||||
sysctl_ctx_init(ð_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(ð_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB CDC Ethernet device side template");
|
||||
SYSCTL_ADD_U16(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_cdce.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_cdce.idProduct, 1, "Product identifier");
|
||||
SYSCTL_ADD_PROC(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"mac", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
ð_mac, sizeof(eth_mac), usb_temp_sysctl,
|
||||
"A", "MAC address string");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"control", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
ð_control, sizeof(eth_control), usb_temp_sysctl,
|
||||
"A", "Control interface string");
|
||||
SYSCTL_ADD_PROC(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"data", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
ð_data, sizeof(eth_data), usb_temp_sysctl,
|
||||
"A", "Data interface string");
|
||||
SYSCTL_ADD_PROC(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"configuration", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
ð_configuration, sizeof(eth_configuration), usb_temp_sysctl,
|
||||
"A", "Configuration string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
ð_manufacturer, sizeof(eth_manufacturer), usb_temp_sysctl,
|
||||
"A", "Manufacturer string");
|
||||
SYSCTL_ADD_PROC(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
ð_product, sizeof(eth_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
SYSCTL_ADD_PROC(ð_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
ð_serial_number, sizeof(eth_serial_number), usb_temp_sysctl,
|
||||
"A", "Serial number string");
|
||||
}
|
||||
|
||||
static void
|
||||
eth_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(ð_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(eth_init, SI_SUB_LOCK, SI_ORDER_FIRST, eth_init, NULL);
|
||||
SYSUNINIT(eth_init, SI_SUB_LOCK, SI_ORDER_FIRST, eth_uninit, NULL);
|
||||
|
@ -2,7 +2,12 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
|
||||
* Copyright (c) 2010 Hans Petter Selasky
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -56,27 +61,26 @@
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_cdc.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
|
||||
enum {
|
||||
INDEX_LANG,
|
||||
INDEX_KEYBOARD,
|
||||
INDEX_PRODUCT,
|
||||
INDEX_MAX,
|
||||
KBD_LANG_INDEX,
|
||||
KBD_INTERFACE_INDEX,
|
||||
KBD_PRODUCT_INDEX,
|
||||
KBD_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_PRODUCT \
|
||||
"K\0e\0y\0b\0o\0a\0r\0d\0 \0T\0e\0s\0t\0 \0D\0e\0v\0i\0c\0e"
|
||||
#define KBD_DEFAULT_INTERFACE "Keyboard Interface"
|
||||
#define KBD_DEFAULT_PRODUCT "Keyboard Test Device"
|
||||
|
||||
#define STRING_KEYBOARD \
|
||||
"K\0e\0y\0b\0o\0a\0r\0d\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
static struct usb_string_descriptor kbd_interface;
|
||||
static struct usb_string_descriptor kbd_product;
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_KEYBOARD, string_keyboard);
|
||||
USB_MAKE_STRING_DESC(STRING_PRODUCT, string_product);
|
||||
static struct sysctl_ctx_list kbd_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -135,7 +139,7 @@ static const struct usb_temp_interface_desc keyboard_iface_0 = {
|
||||
.bInterfaceClass = UICLASS_HID,
|
||||
.bInterfaceSubClass = UISUBCLASS_BOOT,
|
||||
.bInterfaceProtocol = UIPROTO_BOOT_KEYBOARD,
|
||||
.iInterface = INDEX_KEYBOARD,
|
||||
.iInterface = KBD_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc *keyboard_interfaces[] = {
|
||||
@ -147,7 +151,7 @@ static const struct usb_temp_config_desc keyboard_config_desc = {
|
||||
.ppIfaceDesc = keyboard_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = INDEX_PRODUCT,
|
||||
.iConfiguration = KBD_PRODUCT_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *keyboard_configs[] = {
|
||||
@ -158,7 +162,7 @@ static const struct usb_temp_config_desc *keyboard_configs[] = {
|
||||
static usb_temp_get_string_desc_t keyboard_get_string_desc;
|
||||
static usb_temp_get_vendor_desc_t keyboard_get_vendor_desc;
|
||||
|
||||
const struct usb_temp_device_desc usb_template_kbd = {
|
||||
struct usb_temp_device_desc usb_template_kbd = {
|
||||
.getStringDesc = &keyboard_get_string_desc,
|
||||
.getVendorDesc = &keyboard_get_vendor_desc,
|
||||
.ppConfigDesc = keyboard_configs,
|
||||
@ -169,7 +173,7 @@ const struct usb_temp_device_desc usb_template_kbd = {
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = 0,
|
||||
.iProduct = INDEX_PRODUCT,
|
||||
.iProduct = KBD_PRODUCT_INDEX,
|
||||
.iSerialNumber = 0,
|
||||
};
|
||||
|
||||
@ -203,10 +207,10 @@ keyboard_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
|
||||
static const void *
|
||||
keyboard_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[INDEX_MAX] = {
|
||||
[INDEX_LANG] = &usb_string_lang_en,
|
||||
[INDEX_KEYBOARD] = &string_keyboard,
|
||||
[INDEX_PRODUCT] = &string_product,
|
||||
static const void *ptr[KBD_MAX_INDEX] = {
|
||||
[KBD_LANG_INDEX] = &usb_string_lang_en,
|
||||
[KBD_INTERFACE_INDEX] = &kbd_interface,
|
||||
[KBD_PRODUCT_INDEX] = &kbd_product,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -215,8 +219,54 @@ keyboard_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < INDEX_MAX) {
|
||||
if (string_index < KBD_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&kbd_interface, sizeof(kbd_interface),
|
||||
KBD_DEFAULT_INTERFACE);
|
||||
usb_make_str_desc(&kbd_product, sizeof(kbd_product),
|
||||
KBD_DEFAULT_PRODUCT);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_KBD);
|
||||
sysctl_ctx_init(&kbd_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&kbd_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB Keyboard device side template");
|
||||
SYSCTL_ADD_U16(&kbd_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_kbd.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&kbd_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_kbd.idProduct, 1, "Product identifier");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&kbd_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"interface", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&kbd_interface, sizeof(kbd_interface), usb_temp_sysctl,
|
||||
"A", "Interface string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&kbd_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&kbd_product, sizeof(kbd_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&kbd_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(kbd_init, SI_SUB_LOCK, SI_ORDER_FIRST, kbd_init, NULL);
|
||||
SYSUNINIT(kbd_init, SI_SUB_LOCK, SI_ORDER_FIRST, kbd_uninit, NULL);
|
||||
|
@ -1,6 +1,11 @@
|
||||
/* $FreeBSD$ */
|
||||
/*-
|
||||
* Copyright (c) 2015 Hans Petter Selasky. All rights reserved.
|
||||
* Copyright (c) 2015 Hans Petter Selasky
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -53,27 +58,26 @@
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
|
||||
enum {
|
||||
INDEX_MIDI_LANG,
|
||||
INDEX_MIDI_IF,
|
||||
INDEX_MIDI_PRODUCT,
|
||||
INDEX_MIDI_MAX,
|
||||
MIDI_LANG_INDEX,
|
||||
MIDI_INTERFACE_INDEX,
|
||||
MIDI_PRODUCT_INDEX,
|
||||
MIDI_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_MIDI_PRODUCT \
|
||||
"M\0I\0D\0I\0 \0T\0e\0s\0t\0 \0D\0e\0v\0i\0c\0e"
|
||||
#define MIDI_DEFAULT_INTERFACE "MIDI interface"
|
||||
#define MIDI_DEFAULT_PRODUCT "MIDI Test Device"
|
||||
|
||||
#define STRING_MIDI_IF \
|
||||
"M\0I\0D\0I\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
static struct usb_string_descriptor midi_interface;
|
||||
static struct usb_string_descriptor midi_product;
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_MIDI_IF, string_midi_if);
|
||||
USB_MAKE_STRING_DESC(STRING_MIDI_PRODUCT, string_midi_product);
|
||||
static struct sysctl_ctx_list midi_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -92,7 +96,7 @@ static const struct usb_temp_interface_desc midi_iface_0 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_MIDI_IF,
|
||||
.iInterface = MIDI_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_packet_size midi_mps = {
|
||||
@ -174,7 +178,7 @@ static const struct usb_temp_interface_desc midi_iface_1 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_MIDISTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_MIDI_IF,
|
||||
.iInterface = MIDI_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc *midi_interfaces[] = {
|
||||
@ -187,7 +191,7 @@ static const struct usb_temp_config_desc midi_config_desc = {
|
||||
.ppIfaceDesc = midi_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = INDEX_MIDI_PRODUCT,
|
||||
.iConfiguration = MIDI_PRODUCT_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *midi_configs[] = {
|
||||
@ -197,7 +201,7 @@ static const struct usb_temp_config_desc *midi_configs[] = {
|
||||
|
||||
static usb_temp_get_string_desc_t midi_get_string_desc;
|
||||
|
||||
const struct usb_temp_device_desc usb_template_midi = {
|
||||
struct usb_temp_device_desc usb_template_midi = {
|
||||
.getStringDesc = &midi_get_string_desc,
|
||||
.ppConfigDesc = midi_configs,
|
||||
.idVendor = USB_TEMPLATE_VENDOR,
|
||||
@ -207,7 +211,7 @@ const struct usb_temp_device_desc usb_template_midi = {
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = 0,
|
||||
.iProduct = INDEX_MIDI_PRODUCT,
|
||||
.iProduct = MIDI_PRODUCT_INDEX,
|
||||
.iSerialNumber = 0,
|
||||
};
|
||||
|
||||
@ -221,10 +225,10 @@ const struct usb_temp_device_desc usb_template_midi = {
|
||||
static const void *
|
||||
midi_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[INDEX_MIDI_MAX] = {
|
||||
[INDEX_MIDI_LANG] = &usb_string_lang_en,
|
||||
[INDEX_MIDI_IF] = &string_midi_if,
|
||||
[INDEX_MIDI_PRODUCT] = &string_midi_product,
|
||||
static const void *ptr[MIDI_MAX_INDEX] = {
|
||||
[MIDI_LANG_INDEX] = &usb_string_lang_en,
|
||||
[MIDI_INTERFACE_INDEX] = &midi_interface,
|
||||
[MIDI_PRODUCT_INDEX] = &midi_product,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -233,8 +237,54 @@ midi_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < INDEX_MIDI_MAX) {
|
||||
if (string_index < MIDI_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
midi_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&midi_interface, sizeof(midi_interface),
|
||||
MIDI_DEFAULT_INTERFACE);
|
||||
usb_make_str_desc(&midi_product, sizeof(midi_product),
|
||||
MIDI_DEFAULT_PRODUCT);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_MIDI);
|
||||
sysctl_ctx_init(&midi_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&midi_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB MIDI device side template");
|
||||
SYSCTL_ADD_U16(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_midi.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_midi.idProduct, 1, "Product identifier");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"interface", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&midi_interface, sizeof(midi_interface), usb_temp_sysctl,
|
||||
"A", "Interface string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&midi_product, sizeof(midi_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
}
|
||||
|
||||
static void
|
||||
midi_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&midi_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(midi_init, SI_SUB_LOCK, SI_ORDER_FIRST, midi_init, NULL);
|
||||
SYSUNINIT(midi_init, SI_SUB_LOCK, SI_ORDER_FIRST, midi_uninit, NULL);
|
||||
|
@ -2,7 +2,12 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
|
||||
* Copyright (c) 2010 Hans Petter Selasky
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -56,27 +61,26 @@
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_cdc.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
|
||||
enum {
|
||||
INDEX_LANG,
|
||||
INDEX_MODEM,
|
||||
INDEX_PRODUCT,
|
||||
INDEX_MAX,
|
||||
MODEM_LANG_INDEX,
|
||||
MODEM_INTERFACE_INDEX,
|
||||
MODEM_PRODUCT_INDEX,
|
||||
MODEM_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_PRODUCT \
|
||||
"M\0o\0d\0e\0m\0 \0T\0e\0s\0t\0 \0D\0e\0v\0i\0c\0e"
|
||||
#define MODEM_DEFAULT_INTERFACE "Modem interface"
|
||||
#define MODEM_DEFAULT_PRODUCT "Modem Test Device"
|
||||
|
||||
#define STRING_MODEM \
|
||||
"M\0o\0d\0e\0m\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
static struct usb_string_descriptor modem_interface;
|
||||
static struct usb_string_descriptor modem_product;
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_MODEM, string_modem);
|
||||
USB_MAKE_STRING_DESC(STRING_PRODUCT, string_product);
|
||||
static struct sysctl_ctx_list modem_ctx_list;
|
||||
|
||||
#define MODEM_IFACE_0 0
|
||||
#define MODEM_IFACE_1 1
|
||||
@ -161,7 +165,7 @@ static const struct usb_temp_interface_desc modem_iface_0 = {
|
||||
.bInterfaceClass = UICLASS_CDC,
|
||||
.bInterfaceSubClass = UISUBCLASS_ABSTRACT_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = UIPROTO_CDC_AT,
|
||||
.iInterface = INDEX_MODEM,
|
||||
.iInterface = MODEM_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc modem_iface_1 = {
|
||||
@ -169,7 +173,7 @@ static const struct usb_temp_interface_desc modem_iface_1 = {
|
||||
.bInterfaceClass = UICLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = UISUBCLASS_DATA,
|
||||
.bInterfaceProtocol = UIPROTO_CDC_NONE,
|
||||
.iInterface = INDEX_MODEM,
|
||||
.iInterface = MODEM_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc *modem_interfaces[] = {
|
||||
@ -182,7 +186,7 @@ static const struct usb_temp_config_desc modem_config_desc = {
|
||||
.ppIfaceDesc = modem_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = INDEX_PRODUCT,
|
||||
.iConfiguration = MODEM_PRODUCT_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *modem_configs[] = {
|
||||
@ -193,7 +197,7 @@ static const struct usb_temp_config_desc *modem_configs[] = {
|
||||
static usb_temp_get_string_desc_t modem_get_string_desc;
|
||||
static usb_temp_get_vendor_desc_t modem_get_vendor_desc;
|
||||
|
||||
const struct usb_temp_device_desc usb_template_modem = {
|
||||
struct usb_temp_device_desc usb_template_modem = {
|
||||
.getStringDesc = &modem_get_string_desc,
|
||||
.getVendorDesc = &modem_get_vendor_desc,
|
||||
.ppConfigDesc = modem_configs,
|
||||
@ -204,7 +208,7 @@ const struct usb_temp_device_desc usb_template_modem = {
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = 0,
|
||||
.iProduct = INDEX_PRODUCT,
|
||||
.iProduct = MODEM_PRODUCT_INDEX,
|
||||
.iSerialNumber = 0,
|
||||
};
|
||||
|
||||
@ -231,10 +235,10 @@ modem_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
|
||||
static const void *
|
||||
modem_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[INDEX_MAX] = {
|
||||
[INDEX_LANG] = &usb_string_lang_en,
|
||||
[INDEX_MODEM] = &string_modem,
|
||||
[INDEX_PRODUCT] = &string_product,
|
||||
static const void *ptr[MODEM_MAX_INDEX] = {
|
||||
[MODEM_LANG_INDEX] = &usb_string_lang_en,
|
||||
[MODEM_INTERFACE_INDEX] = &modem_interface,
|
||||
[MODEM_PRODUCT_INDEX] = &modem_product,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -243,8 +247,54 @@ modem_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < INDEX_MAX) {
|
||||
if (string_index < MODEM_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
modem_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&modem_interface, sizeof(modem_interface),
|
||||
MODEM_DEFAULT_INTERFACE);
|
||||
usb_make_str_desc(&modem_product, sizeof(modem_product),
|
||||
MODEM_DEFAULT_PRODUCT);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_MODEM);
|
||||
sysctl_ctx_init(&modem_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&modem_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB Modem device side template");
|
||||
SYSCTL_ADD_U16(&modem_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_modem.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&modem_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_modem.idProduct, 1, "Product identifier");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&modem_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"keyboard", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&modem_interface, sizeof(modem_interface), usb_temp_sysctl,
|
||||
"A", "Interface string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&modem_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&modem_product, sizeof(modem_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
}
|
||||
|
||||
static void
|
||||
modem_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&modem_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(modem_init, SI_SUB_LOCK, SI_ORDER_FIRST, modem_init, NULL);
|
||||
SYSUNINIT(modem_init, SI_SUB_LOCK, SI_ORDER_FIRST, modem_uninit, NULL);
|
||||
|
@ -2,7 +2,12 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
|
||||
* Copyright (c) 2010 Hans Petter Selasky
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -56,27 +61,26 @@
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_cdc.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
|
||||
enum {
|
||||
INDEX_LANG,
|
||||
INDEX_MOUSE,
|
||||
INDEX_PRODUCT,
|
||||
INDEX_MAX,
|
||||
MOUSE_LANG_INDEX,
|
||||
MOUSE_INTERFACE_INDEX,
|
||||
MOUSE_PRODUCT_INDEX,
|
||||
MOUSE_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_PRODUCT \
|
||||
"M\0o\0u\0s\0e\0 \0T\0e\0s\0t\0 \0D\0e\0v\0i\0c\0e"
|
||||
#define MOUSE_DEFAULT_INTERFACE "Mouse interface"
|
||||
#define MOUSE_DEFAULT_PRODUCT "Mouse Test Interface"
|
||||
|
||||
#define STRING_MOUSE \
|
||||
"M\0o\0u\0s\0e\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
static struct usb_string_descriptor mouse_interface;
|
||||
static struct usb_string_descriptor mouse_product;
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_MOUSE, string_mouse);
|
||||
USB_MAKE_STRING_DESC(STRING_PRODUCT, string_product);
|
||||
static struct sysctl_ctx_list mouse_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -133,7 +137,7 @@ static const struct usb_temp_interface_desc mouse_iface_0 = {
|
||||
.bInterfaceClass = UICLASS_HID,
|
||||
.bInterfaceSubClass = UISUBCLASS_BOOT,
|
||||
.bInterfaceProtocol = UIPROTO_MOUSE,
|
||||
.iInterface = INDEX_MOUSE,
|
||||
.iInterface = MOUSE_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc *mouse_interfaces[] = {
|
||||
@ -145,7 +149,7 @@ static const struct usb_temp_config_desc mouse_config_desc = {
|
||||
.ppIfaceDesc = mouse_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = INDEX_PRODUCT,
|
||||
.iConfiguration = MOUSE_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *mouse_configs[] = {
|
||||
@ -156,7 +160,7 @@ static const struct usb_temp_config_desc *mouse_configs[] = {
|
||||
static usb_temp_get_string_desc_t mouse_get_string_desc;
|
||||
static usb_temp_get_vendor_desc_t mouse_get_vendor_desc;
|
||||
|
||||
const struct usb_temp_device_desc usb_template_mouse = {
|
||||
struct usb_temp_device_desc usb_template_mouse = {
|
||||
.getStringDesc = &mouse_get_string_desc,
|
||||
.getVendorDesc = &mouse_get_vendor_desc,
|
||||
.ppConfigDesc = mouse_configs,
|
||||
@ -167,7 +171,7 @@ const struct usb_temp_device_desc usb_template_mouse = {
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = 0,
|
||||
.iProduct = INDEX_PRODUCT,
|
||||
.iProduct = MOUSE_PRODUCT_INDEX,
|
||||
.iSerialNumber = 0,
|
||||
};
|
||||
|
||||
@ -201,10 +205,10 @@ mouse_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
|
||||
static const void *
|
||||
mouse_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[INDEX_MAX] = {
|
||||
[INDEX_LANG] = &usb_string_lang_en,
|
||||
[INDEX_MOUSE] = &string_mouse,
|
||||
[INDEX_PRODUCT] = &string_product,
|
||||
static const void *ptr[MOUSE_MAX_INDEX] = {
|
||||
[MOUSE_LANG_INDEX] = &usb_string_lang_en,
|
||||
[MOUSE_INTERFACE_INDEX] = &mouse_interface,
|
||||
[MOUSE_PRODUCT_INDEX] = &mouse_product,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -213,8 +217,54 @@ mouse_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < INDEX_MAX) {
|
||||
if (string_index < MOUSE_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&mouse_interface, sizeof(mouse_interface),
|
||||
MOUSE_DEFAULT_INTERFACE);
|
||||
usb_make_str_desc(&mouse_product, sizeof(mouse_product),
|
||||
MOUSE_DEFAULT_PRODUCT);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_MOUSE);
|
||||
sysctl_ctx_init(&mouse_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&mouse_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB Mouse device side template");
|
||||
SYSCTL_ADD_U16(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_mouse.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_mouse.idProduct, 1, "Product identifier");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"interface", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&mouse_interface, sizeof(mouse_interface), usb_temp_sysctl,
|
||||
"A", "Interface string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&mouse_product, sizeof(mouse_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&mouse_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(mouse_init, SI_SUB_LOCK, SI_ORDER_FIRST, mouse_init, NULL);
|
||||
SYSUNINIT(mouse_init, SI_SUB_LOCK, SI_ORDER_FIRST, mouse_uninit, NULL);
|
||||
|
@ -3,8 +3,12 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2008 Hans Petter Selasky <hselasky@FreeBSD.org>
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -56,43 +60,35 @@
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
|
||||
enum {
|
||||
STRING_LANG_INDEX,
|
||||
STRING_MSC_DATA_INDEX,
|
||||
STRING_MSC_CONFIG_INDEX,
|
||||
STRING_MSC_VENDOR_INDEX,
|
||||
STRING_MSC_PRODUCT_INDEX,
|
||||
STRING_MSC_SERIAL_INDEX,
|
||||
STRING_MSC_MAX,
|
||||
MSC_LANG_INDEX,
|
||||
MSC_INTERFACE_INDEX,
|
||||
MSC_CONFIGURATION_INDEX,
|
||||
MSC_MANUFACTURER_INDEX,
|
||||
MSC_PRODUCT_INDEX,
|
||||
MSC_SERIAL_NUMBER_INDEX,
|
||||
MSC_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_MSC_DATA \
|
||||
"U\0S\0B\0 \0M\0a\0s\0s\0 \0S\0t\0o\0r\0a\0g\0e\0 " \
|
||||
"\0I\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
#define MSC_DEFAULT_INTERFACE "USB Mass Storage Interface"
|
||||
#define MSC_DEFAULT_CONFIGURATION "Default Config"
|
||||
#define MSC_DEFAULT_MANUFACTURER "FreeBSD foundation"
|
||||
#define MSC_DEFAULT_PRODUCT "USB Memory Stick"
|
||||
#define MSC_DEFAULT_SERIAL_NUMBER "March 2008"
|
||||
|
||||
#define STRING_MSC_CONFIG \
|
||||
"D\0e\0f\0a\0u\0l\0t\0 \0c\0o\0n\0f\0i\0g"
|
||||
static struct usb_string_descriptor msc_interface;
|
||||
static struct usb_string_descriptor msc_configuration;
|
||||
static struct usb_string_descriptor msc_manufacturer;
|
||||
static struct usb_string_descriptor msc_product;
|
||||
static struct usb_string_descriptor msc_serial_number;
|
||||
|
||||
#define STRING_MSC_VENDOR \
|
||||
"F\0r\0e\0e\0B\0S\0D\0 \0f\0o\0u\0n\0d\0a\0t\0i\0o\0n"
|
||||
|
||||
#define STRING_MSC_PRODUCT \
|
||||
"U\0S\0B\0 \0M\0e\0m\0o\0r\0y\0 \0S\0t\0i\0c\0k"
|
||||
|
||||
#define STRING_MSC_SERIAL \
|
||||
"M\0a\0r\0c\0h\0 \0002\0000\0000\08"
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_MSC_DATA, string_msc_data);
|
||||
USB_MAKE_STRING_DESC(STRING_MSC_CONFIG, string_msc_config);
|
||||
USB_MAKE_STRING_DESC(STRING_MSC_VENDOR, string_msc_vendor);
|
||||
USB_MAKE_STRING_DESC(STRING_MSC_PRODUCT, string_msc_product);
|
||||
USB_MAKE_STRING_DESC(STRING_MSC_SERIAL, string_msc_serial);
|
||||
static struct sysctl_ctx_list msc_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -134,7 +130,7 @@ static const struct usb_temp_interface_desc msc_data_interface = {
|
||||
.bInterfaceClass = UICLASS_MASS,
|
||||
.bInterfaceSubClass = UISUBCLASS_SCSI,
|
||||
.bInterfaceProtocol = UIPROTO_MASS_BBB,
|
||||
.iInterface = STRING_MSC_DATA_INDEX,
|
||||
.iInterface = MSC_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc *msc_interfaces[] = {
|
||||
@ -146,7 +142,7 @@ static const struct usb_temp_config_desc msc_config_desc = {
|
||||
.ppIfaceDesc = msc_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = STRING_MSC_CONFIG_INDEX,
|
||||
.iConfiguration = MSC_CONFIGURATION_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *msc_configs[] = {
|
||||
@ -154,7 +150,7 @@ static const struct usb_temp_config_desc *msc_configs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
const struct usb_temp_device_desc usb_template_msc = {
|
||||
struct usb_temp_device_desc usb_template_msc = {
|
||||
.getStringDesc = &msc_get_string_desc,
|
||||
.ppConfigDesc = msc_configs,
|
||||
.idVendor = USB_TEMPLATE_VENDOR,
|
||||
@ -163,9 +159,9 @@ const struct usb_temp_device_desc usb_template_msc = {
|
||||
.bDeviceClass = UDCLASS_COMM,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = STRING_MSC_VENDOR_INDEX,
|
||||
.iProduct = STRING_MSC_PRODUCT_INDEX,
|
||||
.iSerialNumber = STRING_MSC_SERIAL_INDEX,
|
||||
.iManufacturer = MSC_MANUFACTURER_INDEX,
|
||||
.iProduct = MSC_PRODUCT_INDEX,
|
||||
.iSerialNumber = MSC_SERIAL_NUMBER_INDEX,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -178,13 +174,13 @@ const struct usb_temp_device_desc usb_template_msc = {
|
||||
static const void *
|
||||
msc_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[STRING_MSC_MAX] = {
|
||||
[STRING_LANG_INDEX] = &usb_string_lang_en,
|
||||
[STRING_MSC_DATA_INDEX] = &string_msc_data,
|
||||
[STRING_MSC_CONFIG_INDEX] = &string_msc_config,
|
||||
[STRING_MSC_VENDOR_INDEX] = &string_msc_vendor,
|
||||
[STRING_MSC_PRODUCT_INDEX] = &string_msc_product,
|
||||
[STRING_MSC_SERIAL_INDEX] = &string_msc_serial,
|
||||
static const void *ptr[MSC_MAX_INDEX] = {
|
||||
[MSC_LANG_INDEX] = &usb_string_lang_en,
|
||||
[MSC_INTERFACE_INDEX] = &msc_interface,
|
||||
[MSC_CONFIGURATION_INDEX] = &msc_configuration,
|
||||
[MSC_MANUFACTURER_INDEX] = &msc_manufacturer,
|
||||
[MSC_PRODUCT_INDEX] = &msc_product,
|
||||
[MSC_SERIAL_NUMBER_INDEX] = &msc_serial_number,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -193,8 +189,72 @@ msc_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < STRING_MSC_MAX) {
|
||||
if (string_index < MSC_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
msc_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&msc_interface, sizeof(msc_interface),
|
||||
MSC_DEFAULT_INTERFACE);
|
||||
usb_make_str_desc(&msc_configuration, sizeof(msc_configuration),
|
||||
MSC_DEFAULT_CONFIGURATION);
|
||||
usb_make_str_desc(&msc_manufacturer, sizeof(msc_manufacturer),
|
||||
MSC_DEFAULT_MANUFACTURER);
|
||||
usb_make_str_desc(&msc_product, sizeof(msc_product),
|
||||
MSC_DEFAULT_PRODUCT);
|
||||
usb_make_str_desc(&msc_serial_number, sizeof(msc_serial_number),
|
||||
MSC_DEFAULT_SERIAL_NUMBER);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_MSC);
|
||||
sysctl_ctx_init(&msc_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&msc_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB Mass Storage device side template");
|
||||
SYSCTL_ADD_U16(&msc_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_msc.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&msc_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_msc.idProduct, 1, "Product identifier");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&msc_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"interface", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&msc_interface, sizeof(msc_interface), usb_temp_sysctl,
|
||||
"A", "Interface string");
|
||||
SYSCTL_ADD_PROC(&msc_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"configuration", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&msc_configuration, sizeof(msc_configuration), usb_temp_sysctl,
|
||||
"A", "Configuration string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&msc_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&msc_manufacturer, sizeof(msc_manufacturer), usb_temp_sysctl,
|
||||
"A", "Manufacturer string");
|
||||
SYSCTL_ADD_PROC(&msc_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&msc_product, sizeof(msc_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
SYSCTL_ADD_PROC(&msc_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&msc_serial_number, sizeof(msc_serial_number), usb_temp_sysctl,
|
||||
"A", "Serial number string");
|
||||
}
|
||||
|
||||
static void
|
||||
msc_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&msc_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(msc_init, SI_SUB_LOCK, SI_ORDER_FIRST, msc_init, NULL);
|
||||
SYSUNINIT(msc_init, SI_SUB_LOCK, SI_ORDER_FIRST, msc_uninit, NULL);
|
||||
|
@ -3,8 +3,12 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2008 Hans Petter Selasky <hselasky@FreeBSD.org>
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -63,6 +67,8 @@
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
@ -70,37 +76,28 @@
|
||||
#define MTP_BREQUEST 0x08
|
||||
|
||||
enum {
|
||||
STRING_LANG_INDEX,
|
||||
STRING_MTP_DATA_INDEX,
|
||||
STRING_MTP_CONFIG_INDEX,
|
||||
STRING_MTP_VENDOR_INDEX,
|
||||
STRING_MTP_PRODUCT_INDEX,
|
||||
STRING_MTP_SERIAL_INDEX,
|
||||
STRING_MTP_MAX,
|
||||
MTP_LANG_INDEX,
|
||||
MTP_INTERFACE_INDEX,
|
||||
MTP_CONFIGURATION_INDEX,
|
||||
MTP_MANUFACTURER_INDEX,
|
||||
MTP_PRODUCT_INDEX,
|
||||
MTP_SERIAL_NUMBER_INDEX,
|
||||
MTP_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_MTP_DATA \
|
||||
"U\0S\0B\0 \0M\0T\0P\0 \0I\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
#define MTP_DEFAULT_INTERFACE "USB MTP Interface"
|
||||
#define MTP_DEFAULT_CONFIGURATION "Default Config"
|
||||
#define MTP_DEFAULT_MANUFACTURER "FreeBSD foundation"
|
||||
#define MTP_DEFAULT_PRODUCT "USB MTP"
|
||||
#define MTP_DEFAULT_SERIAL_NUMBER "June 2008"
|
||||
|
||||
#define STRING_MTP_CONFIG \
|
||||
"D\0e\0f\0a\0u\0l\0t\0 \0c\0o\0n\0f\0i\0g"
|
||||
static struct usb_string_descriptor mtp_interface;
|
||||
static struct usb_string_descriptor mtp_configuration;
|
||||
static struct usb_string_descriptor mtp_manufacturer;
|
||||
static struct usb_string_descriptor mtp_product;
|
||||
static struct usb_string_descriptor mtp_serial_number;
|
||||
|
||||
#define STRING_MTP_VENDOR \
|
||||
"F\0r\0e\0e\0B\0S\0D\0 \0f\0o\0u\0n\0d\0a\0t\0i\0o\0n"
|
||||
|
||||
#define STRING_MTP_PRODUCT \
|
||||
"U\0S\0B\0 \0M\0T\0P"
|
||||
|
||||
#define STRING_MTP_SERIAL \
|
||||
"J\0u\0n\0e\0 \0002\0000\0000\08"
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_MTP_DATA, string_mtp_data);
|
||||
USB_MAKE_STRING_DESC(STRING_MTP_CONFIG, string_mtp_config);
|
||||
USB_MAKE_STRING_DESC(STRING_MTP_VENDOR, string_mtp_vendor);
|
||||
USB_MAKE_STRING_DESC(STRING_MTP_PRODUCT, string_mtp_product);
|
||||
USB_MAKE_STRING_DESC(STRING_MTP_SERIAL, string_mtp_serial);
|
||||
static struct sysctl_ctx_list mtp_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -155,7 +152,7 @@ static const struct usb_temp_interface_desc mtp_data_interface = {
|
||||
.bInterfaceClass = UICLASS_IMAGE,
|
||||
.bInterfaceSubClass = UISUBCLASS_SIC, /* Still Image Class */
|
||||
.bInterfaceProtocol = 1, /* PIMA 15740 */
|
||||
.iInterface = STRING_MTP_DATA_INDEX,
|
||||
.iInterface = MTP_INTERFACE_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc *mtp_interfaces[] = {
|
||||
@ -167,7 +164,7 @@ static const struct usb_temp_config_desc mtp_config_desc = {
|
||||
.ppIfaceDesc = mtp_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = STRING_MTP_CONFIG_INDEX,
|
||||
.iConfiguration = MTP_CONFIGURATION_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *mtp_configs[] = {
|
||||
@ -175,7 +172,7 @@ static const struct usb_temp_config_desc *mtp_configs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
const struct usb_temp_device_desc usb_template_mtp = {
|
||||
struct usb_temp_device_desc usb_template_mtp = {
|
||||
.getStringDesc = &mtp_get_string_desc,
|
||||
.getVendorDesc = &mtp_get_vendor_desc,
|
||||
.ppConfigDesc = mtp_configs,
|
||||
@ -185,9 +182,9 @@ const struct usb_temp_device_desc usb_template_mtp = {
|
||||
.bDeviceClass = 0,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = STRING_MTP_VENDOR_INDEX,
|
||||
.iProduct = STRING_MTP_PRODUCT_INDEX,
|
||||
.iSerialNumber = STRING_MTP_SERIAL_INDEX,
|
||||
.iManufacturer = MTP_MANUFACTURER_INDEX,
|
||||
.iProduct = MTP_PRODUCT_INDEX,
|
||||
.iSerialNumber = MTP_SERIAL_NUMBER_INDEX,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -231,13 +228,13 @@ mtp_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
|
||||
static const void *
|
||||
mtp_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[STRING_MTP_MAX] = {
|
||||
[STRING_LANG_INDEX] = &usb_string_lang_en,
|
||||
[STRING_MTP_DATA_INDEX] = &string_mtp_data,
|
||||
[STRING_MTP_CONFIG_INDEX] = &string_mtp_config,
|
||||
[STRING_MTP_VENDOR_INDEX] = &string_mtp_vendor,
|
||||
[STRING_MTP_PRODUCT_INDEX] = &string_mtp_product,
|
||||
[STRING_MTP_SERIAL_INDEX] = &string_mtp_serial,
|
||||
static const void *ptr[MTP_MAX_INDEX] = {
|
||||
[MTP_LANG_INDEX] = &usb_string_lang_en,
|
||||
[MTP_INTERFACE_INDEX] = &mtp_interface,
|
||||
[MTP_CONFIGURATION_INDEX] = &mtp_configuration,
|
||||
[MTP_MANUFACTURER_INDEX] = &mtp_manufacturer,
|
||||
[MTP_PRODUCT_INDEX] = &mtp_product,
|
||||
[MTP_SERIAL_NUMBER_INDEX] = &mtp_serial_number,
|
||||
};
|
||||
|
||||
static const uint8_t dummy_desc[0x12] = {
|
||||
@ -259,8 +256,72 @@ mtp_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < STRING_MTP_MAX) {
|
||||
if (string_index < MTP_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
mtp_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&mtp_interface, sizeof(mtp_interface),
|
||||
MTP_DEFAULT_INTERFACE);
|
||||
usb_make_str_desc(&mtp_configuration, sizeof(mtp_configuration),
|
||||
MTP_DEFAULT_CONFIGURATION);
|
||||
usb_make_str_desc(&mtp_manufacturer, sizeof(mtp_manufacturer),
|
||||
MTP_DEFAULT_MANUFACTURER);
|
||||
usb_make_str_desc(&mtp_product, sizeof(mtp_product),
|
||||
MTP_DEFAULT_PRODUCT);
|
||||
usb_make_str_desc(&mtp_serial_number, sizeof(mtp_serial_number),
|
||||
MTP_DEFAULT_SERIAL_NUMBER);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_MTP);
|
||||
sysctl_ctx_init(&mtp_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&mtp_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB Media Transfer Protocol device side template");
|
||||
SYSCTL_ADD_U16(&mtp_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_mtp.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&mtp_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_mtp.idProduct, 1, "Product identifier");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&mtp_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"interface", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&mtp_interface, sizeof(mtp_interface), usb_temp_sysctl,
|
||||
"A", "Interface string");
|
||||
SYSCTL_ADD_PROC(&mtp_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"configuration", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&mtp_configuration, sizeof(mtp_configuration), usb_temp_sysctl,
|
||||
"A", "Configuration string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&mtp_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&mtp_manufacturer, sizeof(mtp_manufacturer), usb_temp_sysctl,
|
||||
"A", "Manufacturer string");
|
||||
SYSCTL_ADD_PROC(&mtp_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&mtp_product, sizeof(mtp_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
SYSCTL_ADD_PROC(&mtp_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&mtp_serial_number, sizeof(mtp_serial_number), usb_temp_sysctl,
|
||||
"A", "Serial number string");
|
||||
}
|
||||
|
||||
static void
|
||||
mtp_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&mtp_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(mtp_init, SI_SUB_LOCK, SI_ORDER_FIRST, mtp_init, NULL);
|
||||
SYSUNINIT(mtp_init, SI_SUB_LOCK, SI_ORDER_FIRST, mtp_uninit, NULL);
|
||||
|
@ -1,6 +1,11 @@
|
||||
/* $FreeBSD$ */
|
||||
/*-
|
||||
* Copyright (c) 2014 Hans Petter Selasky. All rights reserved.
|
||||
* Copyright (c) 2014 Hans Petter Selasky
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -54,42 +59,35 @@
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_cdc.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.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,
|
||||
PHONE_LANG_INDEX,
|
||||
PHONE_MIXER_INDEX,
|
||||
PHONE_RECORD_INDEX,
|
||||
PHONE_PLAYBACK_INDEX,
|
||||
PHONE_PRODUCT_INDEX,
|
||||
PHONE_HID_INDEX,
|
||||
PHONE_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_PHONE_PRODUCT \
|
||||
"U\0S\0B\0 \0P\0h\0o\0n\0e\0 \0D\0e\0v\0i\0c\0e"
|
||||
#define PHONE_DEFAULT_MIXER "Mixer interface"
|
||||
#define PHONE_DEFAULT_RECORD "Record interface"
|
||||
#define PHONE_DEFAULT_PLAYBACK "Playback interface"
|
||||
#define PHONE_DEFAULT_PRODUCT "USB Phone Device"
|
||||
#define PHONE_DEFAULT_HID "HID interface"
|
||||
|
||||
#define STRING_PHONE_MIXER \
|
||||
"M\0i\0x\0e\0r\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
static struct usb_string_descriptor phone_mixer;
|
||||
static struct usb_string_descriptor phone_record;
|
||||
static struct usb_string_descriptor phone_playback;
|
||||
static struct usb_string_descriptor phone_product;
|
||||
static struct usb_string_descriptor phone_hid;
|
||||
|
||||
#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);
|
||||
static struct sysctl_ctx_list phone_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -159,7 +157,7 @@ static const struct usb_temp_interface_desc phone_iface_0 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_PHONE_MIXER,
|
||||
.iInterface = PHONE_MIXER_INDEX,
|
||||
};
|
||||
|
||||
static const uint8_t phone_raw_desc_20[] = {
|
||||
@ -216,7 +214,7 @@ static const struct usb_temp_interface_desc phone_iface_1_alt_0 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_PHONE_PLAYBACK,
|
||||
.iInterface = PHONE_PLAYBACK_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc phone_iface_1_alt_1 = {
|
||||
@ -225,7 +223,7 @@ static const struct usb_temp_interface_desc phone_iface_1_alt_1 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_PHONE_PLAYBACK,
|
||||
.iInterface = PHONE_PLAYBACK_INDEX,
|
||||
.isAltInterface = 1, /* this is an alternate setting */
|
||||
};
|
||||
|
||||
@ -273,7 +271,7 @@ static const struct usb_temp_interface_desc phone_iface_2_alt_0 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_PHONE_RECORD,
|
||||
.iInterface = PHONE_RECORD_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc phone_iface_2_alt_1 = {
|
||||
@ -282,7 +280,7 @@ static const struct usb_temp_interface_desc phone_iface_2_alt_1 = {
|
||||
.bInterfaceClass = UICLASS_AUDIO,
|
||||
.bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_PHONE_RECORD,
|
||||
.iInterface = PHONE_RECORD_INDEX,
|
||||
.isAltInterface = 1, /* this is an alternate setting */
|
||||
};
|
||||
|
||||
@ -324,7 +322,7 @@ static const struct usb_temp_interface_desc phone_iface_3 = {
|
||||
.bInterfaceClass = UICLASS_HID,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = INDEX_PHONE_HID,
|
||||
.iInterface = PHONE_HID_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc *phone_interfaces[] = {
|
||||
@ -341,7 +339,7 @@ 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,
|
||||
.iConfiguration = PHONE_PRODUCT_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_config_desc *phone_configs[] = {
|
||||
@ -352,7 +350,7 @@ static const struct usb_temp_config_desc *phone_configs[] = {
|
||||
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 = {
|
||||
struct usb_temp_device_desc usb_template_phone = {
|
||||
.getStringDesc = &phone_get_string_desc,
|
||||
.getVendorDesc = &phone_get_vendor_desc,
|
||||
.ppConfigDesc = phone_configs,
|
||||
@ -363,7 +361,7 @@ const struct usb_temp_device_desc usb_template_phone = {
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = 0,
|
||||
.iProduct = INDEX_PHONE_PRODUCT,
|
||||
.iProduct = PHONE_PRODUCT_INDEX,
|
||||
.iSerialNumber = 0,
|
||||
};
|
||||
|
||||
@ -397,13 +395,13 @@ phone_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
|
||||
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,
|
||||
static const void *ptr[PHONE_MAX_INDEX] = {
|
||||
[PHONE_LANG_INDEX] = &usb_string_lang_en,
|
||||
[PHONE_MIXER_INDEX] = &phone_mixer,
|
||||
[PHONE_RECORD_INDEX] = &phone_record,
|
||||
[PHONE_PLAYBACK_INDEX] = &phone_playback,
|
||||
[PHONE_PRODUCT_INDEX] = &phone_product,
|
||||
[PHONE_HID_INDEX] = &phone_hid,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -412,8 +410,72 @@ phone_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < INDEX_PHONE_MAX) {
|
||||
if (string_index < PHONE_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
phone_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&phone_mixer, sizeof(phone_mixer),
|
||||
PHONE_DEFAULT_MIXER);
|
||||
usb_make_str_desc(&phone_record, sizeof(phone_record),
|
||||
PHONE_DEFAULT_RECORD);
|
||||
usb_make_str_desc(&phone_playback, sizeof(phone_playback),
|
||||
PHONE_DEFAULT_PLAYBACK);
|
||||
usb_make_str_desc(&phone_product, sizeof(phone_product),
|
||||
PHONE_DEFAULT_PRODUCT);
|
||||
usb_make_str_desc(&phone_hid, sizeof(phone_hid),
|
||||
PHONE_DEFAULT_HID);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_PHONE);
|
||||
sysctl_ctx_init(&phone_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&phone_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB Phone device side template");
|
||||
SYSCTL_ADD_U16(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_cdce.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_cdce.idProduct, 1, "Product identifier");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"mixer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&phone_mixer, sizeof(phone_mixer), usb_temp_sysctl,
|
||||
"A", "Mixer interface string");
|
||||
SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"record", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&phone_record, sizeof(phone_record), usb_temp_sysctl,
|
||||
"A", "Record interface string");
|
||||
SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"playback", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&phone_playback, sizeof(phone_playback), usb_temp_sysctl,
|
||||
"A", "Playback interface string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&phone_product, sizeof(phone_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"hid", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&phone_hid, sizeof(phone_hid), usb_temp_sysctl,
|
||||
"A", "HID interface string");
|
||||
}
|
||||
|
||||
static void
|
||||
phone_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&phone_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(phone_init, SI_SUB_LOCK, SI_ORDER_FIRST, phone_init, NULL);
|
||||
SYSUNINIT(phone_init, SI_SUB_LOCK, SI_ORDER_FIRST, phone_uninit, NULL);
|
||||
|
@ -1,11 +1,15 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by SRI International and the University of
|
||||
* Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
|
||||
* ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||
*
|
||||
* Portions of this software were developed by Edward Tomasz Napierala
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -60,6 +64,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_cdc.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/template/usb_template.h>
|
||||
#endif /* USB_GLOBAL_INCLUDE_FILE */
|
||||
@ -68,55 +74,38 @@ __FBSDID("$FreeBSD$");
|
||||
#define MODEM_IFACE_1 1
|
||||
|
||||
enum {
|
||||
STRING_LANG_INDEX,
|
||||
STRING_MODEM_INDEX,
|
||||
STRING_ETH_MAC_INDEX,
|
||||
STRING_ETH_CONTROL_INDEX,
|
||||
STRING_ETH_DATA_INDEX,
|
||||
STRING_ETH_CONFIG_INDEX,
|
||||
STRING_CONFIG_INDEX,
|
||||
STRING_VENDOR_INDEX,
|
||||
STRING_PRODUCT_INDEX,
|
||||
STRING_SERIAL_INDEX,
|
||||
STRING_MAX,
|
||||
SERIALNET_LANG_INDEX,
|
||||
SERIALNET_MODEM_INDEX,
|
||||
SERIALNET_ETH_MAC_INDEX,
|
||||
SERIALNET_ETH_CONTROL_INDEX,
|
||||
SERIALNET_ETH_DATA_INDEX,
|
||||
SERIALNET_ETH_CONFIG_INDEX,
|
||||
SERIALNET_CONFIGURATION_INDEX,
|
||||
SERIALNET_MANUFACTURER_INDEX,
|
||||
SERIALNET_PRODUCT_INDEX,
|
||||
SERIALNET_SERIAL_NUMBER_INDEX,
|
||||
SERIALNET_MAX_INDEX,
|
||||
};
|
||||
|
||||
#define STRING_MODEM \
|
||||
"U\0S\0B\0 \0M\0o\0d\0e\0m\0 \0I\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
#define SERIALNET_DEFAULT_MODEM "USB Modem Interface"
|
||||
#define SERIALNET_DEFAULT_ETH_MAC "2A02030405060789AB"
|
||||
#define SERIALNET_DEFAULT_ETH_CONTROL "USB Ethernet Comm Interface"
|
||||
#define SERIALNET_DEFAULT_ETH_DATA "USB Ethernet Data Interface"
|
||||
#define SERIALNET_DEFAULT_CONFIGURATION "Default configuration"
|
||||
#define SERIALNET_DEFAULT_MANUFACTURER "The FreeBSD Project"
|
||||
#define SERIALNET_DEFAULT_PRODUCT "SERIALNET"
|
||||
#define SERIALNET_DEFAULT_SERIAL_NUMBER "January 2015"
|
||||
|
||||
#define STRING_ETH_MAC \
|
||||
"2\0A\0002\0003\0004\0005\0006\0007\08\09\0A\0B"
|
||||
static struct usb_string_descriptor serialnet_modem;
|
||||
static struct usb_string_descriptor serialnet_eth_mac;
|
||||
static struct usb_string_descriptor serialnet_eth_control;
|
||||
static struct usb_string_descriptor serialnet_eth_data;
|
||||
static struct usb_string_descriptor serialnet_configuration;
|
||||
static struct usb_string_descriptor serialnet_manufacturer;
|
||||
static struct usb_string_descriptor serialnet_product;
|
||||
static struct usb_string_descriptor serialnet_serial_number;
|
||||
|
||||
#define STRING_ETH_CONTROL \
|
||||
"U\0S\0B\0 \0E\0t\0h\0e\0r\0n\0e\0t\0 " \
|
||||
"\0C\0o\0m\0m\0 \0I\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
|
||||
#define STRING_ETH_DATA \
|
||||
"U\0S\0B\0 \0E\0t\0h\0e\0r\0n\0e\0t\0 \0D\0a\0t\0a\0 " \
|
||||
"\0I\0n\0t\0e\0r\0f\0a\0c\0e"
|
||||
|
||||
#define STRING_CONFIG \
|
||||
"D\0e\0f\0a\0u\0l\0t\0 \0c\0o\0n\0f\0i\0g\0u\0r\0a\0t\0i\0o\0n"
|
||||
|
||||
#define STRING_VENDOR \
|
||||
"T\0h\0e\0 \0F\0r\0e\0e\0B\0S\0D\0 \0P\0r\0o\0j\0e\0c\0t"
|
||||
|
||||
#define STRING_PRODUCT \
|
||||
"S\0E\0R\0I\0A\0L\0N\0E\0T"
|
||||
|
||||
#define STRING_SERIAL \
|
||||
"J\0a\0n\0u\0a\0r\0y\0 \0002\0000\0001\0005"
|
||||
|
||||
/* make the real string descriptors */
|
||||
|
||||
USB_MAKE_STRING_DESC(STRING_MODEM, string_modem);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_MAC, string_eth_mac);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_CONTROL, string_eth_control);
|
||||
USB_MAKE_STRING_DESC(STRING_ETH_DATA, string_eth_data);
|
||||
USB_MAKE_STRING_DESC(STRING_CONFIG, string_serialnet_config);
|
||||
USB_MAKE_STRING_DESC(STRING_VENDOR, string_serialnet_vendor);
|
||||
USB_MAKE_STRING_DESC(STRING_PRODUCT, string_serialnet_product);
|
||||
USB_MAKE_STRING_DESC(STRING_SERIAL, string_serialnet_serial);
|
||||
static struct sysctl_ctx_list serialnet_ctx_list;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
@ -142,7 +131,7 @@ static const struct usb_cdc_ethernet_descriptor eth_enf_desc = {
|
||||
.bLength = sizeof(eth_enf_desc),
|
||||
.bDescriptorType = UDESC_CS_INTERFACE,
|
||||
.bDescriptorSubtype = UDESCSUB_CDC_ENF,
|
||||
.iMacAddress = STRING_ETH_MAC_INDEX,
|
||||
.iMacAddress = SERIALNET_ETH_MAC_INDEX,
|
||||
.bmEthernetStatistics = {0, 0, 0, 0},
|
||||
.wMaxSegmentSize = {0xEA, 0x05},/* 1514 bytes */
|
||||
.wNumberMCFilters = {0, 0},
|
||||
@ -203,7 +192,7 @@ static const struct usb_temp_interface_desc eth_control_interface = {
|
||||
.bInterfaceClass = UICLASS_CDC,
|
||||
.bInterfaceSubClass = UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = UIPROTO_CDC_NONE,
|
||||
.iInterface = STRING_ETH_CONTROL_INDEX,
|
||||
.iInterface = SERIALNET_ETH_CONTROL_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_endpoint_desc *eth_data_endpoints[] = {
|
||||
@ -217,7 +206,7 @@ static const struct usb_temp_interface_desc eth_data_null_interface = {
|
||||
.bInterfaceClass = UICLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = UISUBCLASS_DATA,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = STRING_ETH_DATA_INDEX,
|
||||
.iInterface = SERIALNET_ETH_DATA_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc eth_data_interface = {
|
||||
@ -225,7 +214,7 @@ static const struct usb_temp_interface_desc eth_data_interface = {
|
||||
.bInterfaceClass = UICLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = UISUBCLASS_DATA,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = STRING_ETH_DATA_INDEX,
|
||||
.iInterface = SERIALNET_ETH_DATA_INDEX,
|
||||
.isAltInterface = 1, /* this is an alternate setting */
|
||||
};
|
||||
|
||||
@ -307,7 +296,7 @@ static const struct usb_temp_interface_desc modem_iface_0 = {
|
||||
.bInterfaceClass = UICLASS_CDC,
|
||||
.bInterfaceSubClass = UISUBCLASS_ABSTRACT_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = UIPROTO_CDC_AT,
|
||||
.iInterface = STRING_MODEM_INDEX,
|
||||
.iInterface = SERIALNET_MODEM_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc modem_iface_1 = {
|
||||
@ -315,7 +304,7 @@ static const struct usb_temp_interface_desc modem_iface_1 = {
|
||||
.bInterfaceClass = UICLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = UISUBCLASS_DATA,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = STRING_MODEM_INDEX,
|
||||
.iInterface = SERIALNET_MODEM_INDEX,
|
||||
};
|
||||
|
||||
static const struct usb_temp_interface_desc *serialnet_interfaces[] = {
|
||||
@ -331,14 +320,14 @@ static const struct usb_temp_config_desc serialnet_config_desc = {
|
||||
.ppIfaceDesc = serialnet_interfaces,
|
||||
.bmAttributes = UC_BUS_POWERED,
|
||||
.bMaxPower = 25, /* 50 mA */
|
||||
.iConfiguration = STRING_CONFIG_INDEX,
|
||||
.iConfiguration = SERIALNET_CONFIGURATION_INDEX,
|
||||
};
|
||||
static const struct usb_temp_config_desc *serialnet_configs[] = {
|
||||
&serialnet_config_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
const struct usb_temp_device_desc usb_template_serialnet = {
|
||||
struct usb_temp_device_desc usb_template_serialnet = {
|
||||
.getStringDesc = &serialnet_get_string_desc,
|
||||
.ppConfigDesc = serialnet_configs,
|
||||
.idVendor = USB_TEMPLATE_VENDOR,
|
||||
@ -347,9 +336,9 @@ const struct usb_temp_device_desc usb_template_serialnet = {
|
||||
.bDeviceClass = UDCLASS_COMM,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.iManufacturer = STRING_VENDOR_INDEX,
|
||||
.iProduct = STRING_PRODUCT_INDEX,
|
||||
.iSerialNumber = STRING_SERIAL_INDEX,
|
||||
.iManufacturer = SERIALNET_MANUFACTURER_INDEX,
|
||||
.iProduct = SERIALNET_PRODUCT_INDEX,
|
||||
.iSerialNumber = SERIALNET_SERIAL_NUMBER_INDEX,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -362,16 +351,16 @@ const struct usb_temp_device_desc usb_template_serialnet = {
|
||||
static const void *
|
||||
serialnet_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
{
|
||||
static const void *ptr[STRING_MAX] = {
|
||||
[STRING_LANG_INDEX] = &usb_string_lang_en,
|
||||
[STRING_MODEM_INDEX] = &string_modem,
|
||||
[STRING_ETH_MAC_INDEX] = &string_eth_mac,
|
||||
[STRING_ETH_CONTROL_INDEX] = &string_eth_control,
|
||||
[STRING_ETH_DATA_INDEX] = &string_eth_data,
|
||||
[STRING_CONFIG_INDEX] = &string_serialnet_config,
|
||||
[STRING_VENDOR_INDEX] = &string_serialnet_vendor,
|
||||
[STRING_PRODUCT_INDEX] = &string_serialnet_product,
|
||||
[STRING_SERIAL_INDEX] = &string_serialnet_serial,
|
||||
static const void *ptr[SERIALNET_MAX_INDEX] = {
|
||||
[SERIALNET_LANG_INDEX] = &usb_string_lang_en,
|
||||
[SERIALNET_MODEM_INDEX] = &serialnet_modem,
|
||||
[SERIALNET_ETH_MAC_INDEX] = &serialnet_eth_mac,
|
||||
[SERIALNET_ETH_CONTROL_INDEX] = &serialnet_eth_control,
|
||||
[SERIALNET_ETH_DATA_INDEX] = &serialnet_eth_data,
|
||||
[SERIALNET_CONFIGURATION_INDEX] = &serialnet_configuration,
|
||||
[SERIALNET_MANUFACTURER_INDEX] = &serialnet_manufacturer,
|
||||
[SERIALNET_PRODUCT_INDEX] = &serialnet_product,
|
||||
[SERIALNET_SERIAL_NUMBER_INDEX] = &serialnet_serial_number,
|
||||
};
|
||||
|
||||
if (string_index == 0) {
|
||||
@ -380,8 +369,90 @@ serialnet_get_string_desc(uint16_t lang_id, uint8_t string_index)
|
||||
if (lang_id != 0x0409) {
|
||||
return (NULL);
|
||||
}
|
||||
if (string_index < STRING_MAX) {
|
||||
if (string_index < SERIALNET_MAX_INDEX) {
|
||||
return (ptr[string_index]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
serialnet_init(void *arg __unused)
|
||||
{
|
||||
struct sysctl_oid *parent;
|
||||
char parent_name[3];
|
||||
|
||||
usb_make_str_desc(&serialnet_modem, sizeof(serialnet_modem),
|
||||
SERIALNET_DEFAULT_MODEM);
|
||||
usb_make_str_desc(&serialnet_eth_mac, sizeof(serialnet_eth_mac),
|
||||
SERIALNET_DEFAULT_ETH_MAC);
|
||||
usb_make_str_desc(&serialnet_eth_control, sizeof(serialnet_eth_control),
|
||||
SERIALNET_DEFAULT_ETH_CONTROL);
|
||||
usb_make_str_desc(&serialnet_eth_data, sizeof(serialnet_eth_data),
|
||||
SERIALNET_DEFAULT_ETH_DATA);
|
||||
usb_make_str_desc(&serialnet_configuration, sizeof(serialnet_configuration),
|
||||
SERIALNET_DEFAULT_CONFIGURATION);
|
||||
usb_make_str_desc(&serialnet_manufacturer, sizeof(serialnet_manufacturer),
|
||||
SERIALNET_DEFAULT_MANUFACTURER);
|
||||
usb_make_str_desc(&serialnet_product, sizeof(serialnet_product),
|
||||
SERIALNET_DEFAULT_PRODUCT);
|
||||
usb_make_str_desc(&serialnet_serial_number, sizeof(serialnet_serial_number),
|
||||
SERIALNET_DEFAULT_SERIAL_NUMBER);
|
||||
|
||||
snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_SERIALNET);
|
||||
sysctl_ctx_init(&serialnet_ctx_list);
|
||||
|
||||
parent = SYSCTL_ADD_NODE(&serialnet_ctx_list,
|
||||
SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
|
||||
parent_name, CTLFLAG_RW,
|
||||
0, "USB Mass Storage device side template");
|
||||
SYSCTL_ADD_U16(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"vendor_id", CTLFLAG_RWTUN,
|
||||
&usb_template_serialnet.idVendor, 1, "Vendor identifier");
|
||||
SYSCTL_ADD_U16(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product_id", CTLFLAG_RWTUN,
|
||||
&usb_template_serialnet.idProduct, 1, "Product identifier");
|
||||
SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"eth_mac", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&serialnet_eth_mac, sizeof(serialnet_eth_mac), usb_temp_sysctl,
|
||||
"A", "Ethernet MAC address string");
|
||||
#if 0
|
||||
SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"modem", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&serialnet_modem, sizeof(serialnet_modem), usb_temp_sysctl,
|
||||
"A", "Modem interface string");
|
||||
SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"eth_control", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&serialnet_eth_control, sizeof(serialnet_eth_data), usb_temp_sysctl,
|
||||
"A", "Ethernet control interface string");
|
||||
SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"eth_data", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&serialnet_eth_data, sizeof(serialnet_eth_data), usb_temp_sysctl,
|
||||
"A", "Ethernet data interface string");
|
||||
SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"configuration", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&serialnet_configuration, sizeof(serialnet_configuration), usb_temp_sysctl,
|
||||
"A", "Configuration string");
|
||||
#endif
|
||||
SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&serialnet_manufacturer, sizeof(serialnet_manufacturer), usb_temp_sysctl,
|
||||
"A", "Manufacturer string");
|
||||
SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&serialnet_product, sizeof(serialnet_product), usb_temp_sysctl,
|
||||
"A", "Product string");
|
||||
SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
"serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&serialnet_serial_number, sizeof(serialnet_serial_number), usb_temp_sysctl,
|
||||
"A", "Serial number string");
|
||||
}
|
||||
|
||||
static void
|
||||
serialnet_uninit(void *arg __unused)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&serialnet_ctx_list);
|
||||
}
|
||||
|
||||
SYSINIT(serialnet_init, SI_SUB_LOCK, SI_ORDER_FIRST, serialnet_init, NULL);
|
||||
SYSUNINIT(serialnet_init, SI_SUB_LOCK, SI_ORDER_FIRST, serialnet_uninit, NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user