[patch] proof of concept: enable/disable usb devices from user mode
People on misc@ asked if it is possible to disable usb devices without reboot.
Some of them want to disable cameras on laptops to save energy,
other people want to disable mass storages on servers where
it is not easy to disconnect cable.
Any usb device is connected to hub's port, and any hub knows how to
disable port and power off it, so I decided to create such API and tool.
Disclamer: this is the first time I do unix kernel development,
and this tool is not ready to be commited: I just want to make sure that
my idea is generally accepted by tech@.
This is how it works:
* usb(4) has ioctl to enable/disable port on uhub(4)
* usbports accepts device number, hub address, port number and status
* it then forwards it to usb(4), which delegates command to uhub(4)
* usbd_detach() called to inform usb(4) that device is disabled
* to enable, port is enabled, powered and reseted, so usb(4) finds device
To find hub number use usbdevs(8)
Consider following output
$ usbdevs -v
addr 1: ...
port 1 addr 2: high speed, self powered, config 1, Rate Matching Hub(0x0024)
port 1 powered
port 2 addr 3: low speed, power 100 mA, config 1, USB Optical Mouse(0xc077)
That means we have bus=1 (usb1), hub_addr=2 (addr 2), port=2 (port 2)
$ doas usbports 1 2 2 0
This will disable mouse.
$ doas usbports 1 2 2 1
This will enable mouse back.
If people accept this approach, here are my plans:
Fix kernel API (check port status before disable/enable, write man).
Merge usbdevs and usbports (there should be one tool for usb).
Write man about tool.
Create TUI/GUI tool that displays usb ports tree providing user with ability
to click on port to disable/enable it.
This tool may also have command line interface and use device ids instead of
ports, so user may write starting script to persist changes.
Add ability to disable port on root hub: whole controller could be disabled
in *hci specific-manner, so I will add method to each *hci to do that.
For example: in ehci you use PORTC to disable port.
By the way:
In Windows they have device manager (UI for PnPmanager) that gives user
ability to disable any node in tree.
When node is disabled, all its ancestors are disabled first in device-specific
USB controller could be disabled using PCI power API because
*hci is PCI device.
PCI controller could be disabled using ACPI.
I like idea of "tool to show device tree and disable any device" which
is bus-agnostic, but not sure if it does not compromise security and stability,
and it seems to be huge task.
Since header files in dev/usb/ changed, make sure you have them in
/usr/include/dev/usb to compile usbports.