diff --git a/share/man/man4/usb_template.4 b/share/man/man4/usb_template.4 index 35f8bf58963e..e1bea49e1938 100644 --- a/share/man/man4/usb_template.4 +++ b/share/man/man4/usb_template.4 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 17, 2018 +.Dd May 23, 2018 .Dt USB_TEMPLATE 4 .Os . @@ -100,6 +100,11 @@ tunables: .It Va hw.usb.template Currently selected template. 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 Configuration for template number .Va N . diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c index e0898c0d1e76..44170c8103bd 100644 --- a/sys/dev/usb/template/usb_template.c +++ b/sys/dev/usb/template/usb_template.c @@ -76,14 +76,12 @@ #include #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); /* 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_endpoint_desc(struct usb_temp_setup *, 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); 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 * @@ -426,6 +451,7 @@ usb_make_config_desc(struct usb_temp_setup *temp, struct usb_config_descriptor *cd; const struct usb_temp_interface_desc **tid; uint16_t old_size; + int power; /* Reserve memory */ @@ -463,13 +489,16 @@ usb_make_config_desc(struct usb_temp_setup *temp, cd->bConfigurationValue = temp->bConfigurationValue; cd->iConfiguration = tcd->iConfiguration; cd->bmAttributes = tcd->bmAttributes; - cd->bMaxPower = tcd->bMaxPower; - cd->bmAttributes |= (UC_REMOTE_WAKEUP | UC_BUS_POWERED); - if (temp->self_powered) { - cd->bmAttributes |= UC_SELF_POWERED; - } else { + power = usb_template_power; + cd->bMaxPower = power / 2; /* 2 mA units */ + cd->bmAttributes |= UC_REMOTE_WAKEUP; + if (power > 0) { + cd->bmAttributes |= UC_BUS_POWERED; cd->bmAttributes &= ~UC_SELF_POWERED; + } else { + cd->bmAttributes &= ~UC_BUS_POWERED; + cd->bmAttributes |= UC_SELF_POWERED; } } } diff --git a/sys/dev/usb/template/usb_template_audio.c b/sys/dev/usb/template/usb_template_audio.c index c332437371e3..40861d42db51 100644 --- a/sys/dev/usb/template/usb_template_audio.c +++ b/sys/dev/usb/template/usb_template_audio.c @@ -351,8 +351,8 @@ static const struct usb_temp_interface_desc *audio_interfaces[] = { static const struct usb_temp_config_desc audio_config_desc = { .ppIfaceDesc = audio_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = AUDIO_PRODUCT_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_cdce.c b/sys/dev/usb/template/usb_template_cdce.c index d5d0a8701818..9bfcd6c74fa0 100644 --- a/sys/dev/usb/template/usb_template_cdce.c +++ b/sys/dev/usb/template/usb_template_cdce.c @@ -219,8 +219,8 @@ static const struct usb_temp_interface_desc *eth_interfaces[] = { static const struct usb_temp_config_desc eth_config_desc = { .ppIfaceDesc = eth_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = ETH_CONFIGURATION_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_kbd.c b/sys/dev/usb/template/usb_template_kbd.c index 7507e73b8035..fd2e8d9fbf5a 100644 --- a/sys/dev/usb/template/usb_template_kbd.c +++ b/sys/dev/usb/template/usb_template_kbd.c @@ -157,8 +157,8 @@ static const struct usb_temp_interface_desc *keyboard_interfaces[] = { static const struct usb_temp_config_desc keyboard_config_desc = { .ppIfaceDesc = keyboard_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = KBD_PRODUCT_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_midi.c b/sys/dev/usb/template/usb_template_midi.c index 2b0e66f938b7..8f4acdb80a80 100644 --- a/sys/dev/usb/template/usb_template_midi.c +++ b/sys/dev/usb/template/usb_template_midi.c @@ -199,8 +199,8 @@ static const struct usb_temp_interface_desc *midi_interfaces[] = { static const struct usb_temp_config_desc midi_config_desc = { .ppIfaceDesc = midi_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = MIDI_PRODUCT_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_modem.c b/sys/dev/usb/template/usb_template_modem.c index 66229e736ab6..5f52212ab178 100644 --- a/sys/dev/usb/template/usb_template_modem.c +++ b/sys/dev/usb/template/usb_template_modem.c @@ -198,8 +198,8 @@ static const struct usb_temp_interface_desc *modem_interfaces[] = { static const struct usb_temp_config_desc modem_config_desc = { .ppIfaceDesc = modem_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = MODEM_PRODUCT_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_mouse.c b/sys/dev/usb/template/usb_template_mouse.c index 483962934285..5154925fd2ba 100644 --- a/sys/dev/usb/template/usb_template_mouse.c +++ b/sys/dev/usb/template/usb_template_mouse.c @@ -155,8 +155,8 @@ static const struct usb_temp_interface_desc *mouse_interfaces[] = { static const struct usb_temp_config_desc mouse_config_desc = { .ppIfaceDesc = mouse_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = MOUSE_INTERFACE_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_msc.c b/sys/dev/usb/template/usb_template_msc.c index 21daf003bb85..3d9e83df8db2 100644 --- a/sys/dev/usb/template/usb_template_msc.c +++ b/sys/dev/usb/template/usb_template_msc.c @@ -142,8 +142,8 @@ static const struct usb_temp_interface_desc *msc_interfaces[] = { static const struct usb_temp_config_desc msc_config_desc = { .ppIfaceDesc = msc_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = MSC_CONFIGURATION_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_mtp.c b/sys/dev/usb/template/usb_template_mtp.c index 76e2a51a65c9..1441b32a457c 100644 --- a/sys/dev/usb/template/usb_template_mtp.c +++ b/sys/dev/usb/template/usb_template_mtp.c @@ -164,8 +164,8 @@ static const struct usb_temp_interface_desc *mtp_interfaces[] = { static const struct usb_temp_config_desc mtp_config_desc = { .ppIfaceDesc = mtp_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = MTP_CONFIGURATION_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_multi.c b/sys/dev/usb/template/usb_template_multi.c index 7f3226873475..32ae72ca40f8 100644 --- a/sys/dev/usb/template/usb_template_multi.c +++ b/sys/dev/usb/template/usb_template_multi.c @@ -370,8 +370,8 @@ static const struct usb_temp_interface_desc *multi_interfaces[] = { static const struct usb_temp_config_desc multi_config_desc = { .ppIfaceDesc = multi_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = MULTI_CONFIGURATION_INDEX, }; static const struct usb_temp_config_desc *multi_configs[] = { diff --git a/sys/dev/usb/template/usb_template_phone.c b/sys/dev/usb/template/usb_template_phone.c index a9c684478fc2..189a32af80fe 100644 --- a/sys/dev/usb/template/usb_template_phone.c +++ b/sys/dev/usb/template/usb_template_phone.c @@ -347,8 +347,8 @@ static const struct usb_temp_interface_desc *phone_interfaces[] = { static const struct usb_temp_config_desc phone_config_desc = { .ppIfaceDesc = phone_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = PHONE_PRODUCT_INDEX, }; diff --git a/sys/dev/usb/template/usb_template_serialnet.c b/sys/dev/usb/template/usb_template_serialnet.c index afc6ab493fb6..b2aea39978a2 100644 --- a/sys/dev/usb/template/usb_template_serialnet.c +++ b/sys/dev/usb/template/usb_template_serialnet.c @@ -327,8 +327,8 @@ static const struct usb_temp_interface_desc *serialnet_interfaces[] = { static const struct usb_temp_config_desc serialnet_config_desc = { .ppIfaceDesc = serialnet_interfaces, - .bmAttributes = UC_BUS_POWERED, - .bMaxPower = 25, /* 50 mA */ + .bmAttributes = 0, + .bMaxPower = 0, .iConfiguration = SERIALNET_CONFIGURATION_INDEX, }; static const struct usb_temp_config_desc *serialnet_configs[] = {