Centralize USB device mode bus power reporting, and add

hw.usb.template_power sysctl to control it.

Reviewed by:	hselasky@ (earlier version)
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Edward Tomasz Napierala 2018-05-23 20:06:04 +00:00
parent 95104040a3
commit d008c0d75f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=334115
13 changed files with 65 additions and 31 deletions

View File

@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd May 17, 2018 .Dd May 23, 2018
.Dt USB_TEMPLATE 4 .Dt USB_TEMPLATE 4
.Os .Os
. .
@ -100,6 +100,11 @@ tunables:
.It Va hw.usb.template .It Va hw.usb.template
Currently selected template. Currently selected template.
Set to -1 to make the device disappear from the USB host point of view. Set to -1 to make the device disappear from the USB host point of view.
.It Va hw.usb.template_power
USB bus power consumption in mA.
Must be between 0 and 500.
Setting to 0 marks the device as self-powered.
Defaults to 500mA.
.It Va hw.usb.templates.N .It Va hw.usb.templates.N
Configuration for template number Configuration for template number
.Va N . .Va N .

View File

@ -76,14 +76,12 @@
#include <dev/usb/template/usb_template.h> #include <dev/usb/template/usb_template.h>
#endif /* USB_GLOBAL_INCLUDE_FILE */ #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_DEPEND(usb_template, usb, 1, 1, 1);
MODULE_VERSION(usb_template, 1); MODULE_VERSION(usb_template, 1);
/* function prototypes */ /* function prototypes */
static int sysctl_hw_usb_template_power(SYSCTL_HANDLER_ARGS);
static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *); static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *);
static void usb_make_endpoint_desc(struct usb_temp_setup *, static void usb_make_endpoint_desc(struct usb_temp_setup *,
const struct usb_temp_endpoint_desc *); const struct usb_temp_endpoint_desc *);
@ -117,6 +115,33 @@ static usb_error_t usb_temp_setup_by_index(struct usb_device *,
uint16_t index); uint16_t index);
static void usb_temp_init(void *); static void usb_temp_init(void *);
SYSCTL_NODE(_hw_usb, OID_AUTO, templates, CTLFLAG_RW, 0,
"USB device side templates");
SYSCTL_PROC(_hw_usb, OID_AUTO, template_power,
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
NULL, 0, sysctl_hw_usb_template_power,
"I", "USB bus power consumption in mA");
static int usb_template_power = 500; /* 500mA */
static int
sysctl_hw_usb_template_power(SYSCTL_HANDLER_ARGS)
{
int error, val;
val = usb_template_power;
error = sysctl_handle_int(oidp, &val, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
if (val < 0 || val > 500)
return (EINVAL);
usb_template_power = val;
return (0);
}
/*------------------------------------------------------------------------* /*------------------------------------------------------------------------*
* usb_decode_str_desc * usb_decode_str_desc
* *
@ -426,6 +451,7 @@ usb_make_config_desc(struct usb_temp_setup *temp,
struct usb_config_descriptor *cd; struct usb_config_descriptor *cd;
const struct usb_temp_interface_desc **tid; const struct usb_temp_interface_desc **tid;
uint16_t old_size; uint16_t old_size;
int power;
/* Reserve memory */ /* Reserve memory */
@ -463,13 +489,16 @@ usb_make_config_desc(struct usb_temp_setup *temp,
cd->bConfigurationValue = temp->bConfigurationValue; cd->bConfigurationValue = temp->bConfigurationValue;
cd->iConfiguration = tcd->iConfiguration; cd->iConfiguration = tcd->iConfiguration;
cd->bmAttributes = tcd->bmAttributes; cd->bmAttributes = tcd->bmAttributes;
cd->bMaxPower = tcd->bMaxPower;
cd->bmAttributes |= (UC_REMOTE_WAKEUP | UC_BUS_POWERED);
if (temp->self_powered) { power = usb_template_power;
cd->bmAttributes |= UC_SELF_POWERED; cd->bMaxPower = power / 2; /* 2 mA units */
} else { cd->bmAttributes |= UC_REMOTE_WAKEUP;
if (power > 0) {
cd->bmAttributes |= UC_BUS_POWERED;
cd->bmAttributes &= ~UC_SELF_POWERED; cd->bmAttributes &= ~UC_SELF_POWERED;
} else {
cd->bmAttributes &= ~UC_BUS_POWERED;
cd->bmAttributes |= UC_SELF_POWERED;
} }
} }
} }

View File

@ -351,8 +351,8 @@ static const struct usb_temp_interface_desc *audio_interfaces[] = {
static const struct usb_temp_config_desc audio_config_desc = { static const struct usb_temp_config_desc audio_config_desc = {
.ppIfaceDesc = audio_interfaces, .ppIfaceDesc = audio_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = AUDIO_PRODUCT_INDEX, .iConfiguration = AUDIO_PRODUCT_INDEX,
}; };

View File

@ -219,8 +219,8 @@ static const struct usb_temp_interface_desc *eth_interfaces[] = {
static const struct usb_temp_config_desc eth_config_desc = { static const struct usb_temp_config_desc eth_config_desc = {
.ppIfaceDesc = eth_interfaces, .ppIfaceDesc = eth_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = ETH_CONFIGURATION_INDEX, .iConfiguration = ETH_CONFIGURATION_INDEX,
}; };

View File

@ -157,8 +157,8 @@ static const struct usb_temp_interface_desc *keyboard_interfaces[] = {
static const struct usb_temp_config_desc keyboard_config_desc = { static const struct usb_temp_config_desc keyboard_config_desc = {
.ppIfaceDesc = keyboard_interfaces, .ppIfaceDesc = keyboard_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = KBD_PRODUCT_INDEX, .iConfiguration = KBD_PRODUCT_INDEX,
}; };

View File

@ -199,8 +199,8 @@ static const struct usb_temp_interface_desc *midi_interfaces[] = {
static const struct usb_temp_config_desc midi_config_desc = { static const struct usb_temp_config_desc midi_config_desc = {
.ppIfaceDesc = midi_interfaces, .ppIfaceDesc = midi_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = MIDI_PRODUCT_INDEX, .iConfiguration = MIDI_PRODUCT_INDEX,
}; };

View File

@ -198,8 +198,8 @@ static const struct usb_temp_interface_desc *modem_interfaces[] = {
static const struct usb_temp_config_desc modem_config_desc = { static const struct usb_temp_config_desc modem_config_desc = {
.ppIfaceDesc = modem_interfaces, .ppIfaceDesc = modem_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = MODEM_PRODUCT_INDEX, .iConfiguration = MODEM_PRODUCT_INDEX,
}; };

View File

@ -155,8 +155,8 @@ static const struct usb_temp_interface_desc *mouse_interfaces[] = {
static const struct usb_temp_config_desc mouse_config_desc = { static const struct usb_temp_config_desc mouse_config_desc = {
.ppIfaceDesc = mouse_interfaces, .ppIfaceDesc = mouse_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = MOUSE_INTERFACE_INDEX, .iConfiguration = MOUSE_INTERFACE_INDEX,
}; };

View File

@ -142,8 +142,8 @@ static const struct usb_temp_interface_desc *msc_interfaces[] = {
static const struct usb_temp_config_desc msc_config_desc = { static const struct usb_temp_config_desc msc_config_desc = {
.ppIfaceDesc = msc_interfaces, .ppIfaceDesc = msc_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = MSC_CONFIGURATION_INDEX, .iConfiguration = MSC_CONFIGURATION_INDEX,
}; };

View File

@ -164,8 +164,8 @@ static const struct usb_temp_interface_desc *mtp_interfaces[] = {
static const struct usb_temp_config_desc mtp_config_desc = { static const struct usb_temp_config_desc mtp_config_desc = {
.ppIfaceDesc = mtp_interfaces, .ppIfaceDesc = mtp_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = MTP_CONFIGURATION_INDEX, .iConfiguration = MTP_CONFIGURATION_INDEX,
}; };

View File

@ -370,8 +370,8 @@ static const struct usb_temp_interface_desc *multi_interfaces[] = {
static const struct usb_temp_config_desc multi_config_desc = { static const struct usb_temp_config_desc multi_config_desc = {
.ppIfaceDesc = multi_interfaces, .ppIfaceDesc = multi_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = MULTI_CONFIGURATION_INDEX, .iConfiguration = MULTI_CONFIGURATION_INDEX,
}; };
static const struct usb_temp_config_desc *multi_configs[] = { static const struct usb_temp_config_desc *multi_configs[] = {

View File

@ -347,8 +347,8 @@ static const struct usb_temp_interface_desc *phone_interfaces[] = {
static const struct usb_temp_config_desc phone_config_desc = { static const struct usb_temp_config_desc phone_config_desc = {
.ppIfaceDesc = phone_interfaces, .ppIfaceDesc = phone_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = PHONE_PRODUCT_INDEX, .iConfiguration = PHONE_PRODUCT_INDEX,
}; };

View File

@ -327,8 +327,8 @@ static const struct usb_temp_interface_desc *serialnet_interfaces[] = {
static const struct usb_temp_config_desc serialnet_config_desc = { static const struct usb_temp_config_desc serialnet_config_desc = {
.ppIfaceDesc = serialnet_interfaces, .ppIfaceDesc = serialnet_interfaces,
.bmAttributes = UC_BUS_POWERED, .bmAttributes = 0,
.bMaxPower = 25, /* 50 mA */ .bMaxPower = 0,
.iConfiguration = SERIALNET_CONFIGURATION_INDEX, .iConfiguration = SERIALNET_CONFIGURATION_INDEX,
}; };
static const struct usb_temp_config_desc *serialnet_configs[] = { static const struct usb_temp_config_desc *serialnet_configs[] = {