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:
parent
95104040a3
commit
d008c0d75f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=334115
@ -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 .
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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[] = {
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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[] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user