The following patch adds the ability to read power draw on usb devices.
I have used ioctl 135. I don't know what the protocol is for assigning
numbers, so this may be unacceptable?
ugen is patched to export the data via ioctl
libusb20 and usbconfig are patched to make use of it (end-of-line):
[mattb@falcon ~]$ usbconfig
ugen0.1: at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps)
pwr=SAVE (0mA)
ugen1.1: at usbus1, cfg=0 md=HOST spd=SUPER (5.0Gbps)
pwr=SAVE (0mA)
ugen2.1: at usbus2, cfg=0 md=HOST spd=SUPER (5.0Gbps)
pwr=SAVE (0mA)
ugen3.1: at usbus3, cfg=0 md=HOST spd=HIGH (480Mbps)
pwr=SAVE (0mA)
ugen0.2: at usbus0, cfg=0 md=HOST spd=HIGH
(480Mbps) pwr=SAVE (0mA)
ugen3.2: at usbus3, cfg=0 md=HOST spd=HIGH
(480Mbps) pwr=SAVE (0mA)
ugen3.3: at usbus3, cfg=0 md=HOST spd=LOW (1.5Mbps)
pwr=ON (70mA)
ugen3.4: at usbus3, cfg=0 md=HOST spd=FULL
(12Mbps) pwr=ON (98mA)
ugen3.5: at usbus3, cfg=0 md=HOST spd=FULL
(12Mbps) pwr=ON (0mA)
ugen3.6: at usbus3, cfg=0 md=HOST spd=FULL
(12Mbps) pwr=ON (100mA)
diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3
index af80c6c..8753e06 100644
--- a/lib/libusb/libusb20.3
+++ b/lib/libusb/libusb20.3
@@ -149,6 +149,8 @@ USB access library (libusb -lusb)
.Fn libusb20_dev_set_power_mode "struct libusb20_device *pdev" "uint8_t
power_mode"
.Ft uint8_t
.Fn libusb20_dev_get_power_mode "struct libusb20_device *pdev"
+.Ft uint16_t
+.Fn libusb20_dev_get_power_usage "struct libusb20_device *pdev"
.Ft int
.Fn libusb20_dev_set_alt_index "struct libusb20_device *pdev" "uint8_t
iface_index" "uint8_t alt_index"
.Ft struct LIBUSB20_DEVICE_DESC_DECODED *
@@ -740,6 +742,11 @@ USB device.
.
.Pp
.
+.Fn libusb20_dev_get_power_usage
+returns the reported power usage in milliamps for the given USB device.
+.
+.Pp
+.
.Fn libusb20_dev_set_alt_index
will try to set the given alternate index for the given
USB interface index.
diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c
index aa45991..ce75511 100644
--- a/lib/libusb/libusb20.c
+++ b/lib/libusb/libusb20.c
@@ -71,6 +71,7 @@ dummy_callback(struct libusb20_transfer *xfer)
#definedummy_check_connected (void *)dummy_int
#definedummy_set_power_mode (void *)dummy_int
#definedummy_get_power_mode (void *)dummy_int
+#definedummy_get_power_usage (void *)dummy_int
#definedummy_kernel_driver_active (void *)dummy_int
#definedummy_detach_kernel_driver (void *)dummy_int
#definedummy_do_request_sync (void *)dummy_int
@@ -717,6 +718,18 @@ libusb20_dev_get_power_mode(struct libusb20_device *pdev)
return (power_mode);
}
+uint16_t
+libusb20_dev_get_power_usage(struct libusb20_device *pdev)
+{
+ int error;
+ uint16_t power_usage;
+
+ error = pdev->methods->get_power_usage(pdev, &power_usage);
+ if (error)
+ power_usage = 0;
+ return (power_usage);
+}
+
int
libusb20_dev_set_alt_index(struct libusb20_device *pdev, uint8_t ifaceIndex,
uint8_t altIndex)
{
diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h
index 87e0572..81928b1 100644
--- a/lib/libusb/libusb20.h
+++ b/lib/libusb/libusb20.h
@@ -255,6 +255,7 @@ int libusb20_dev_reset(struct libusb20_device *pdev);
intlibusb20_dev_check_connected(struct libusb20_device *pdev);
intlibusb20_dev_set_power_mode(struct libusb20_device *pdev, uint8_t
power_mode);
uint8_tlibusb20_dev_get_power_mode(struct libusb20_device *pdev);
+uint16_t libusb20_dev_get_power_usage(struct libusb20_device *pdev);
intlibusb20_dev_set_alt_index(struct libusb20_device *pdev, uint8_t
iface_index, uint8_t alt_index);
intlibusb20_dev_get_info(struct libusb20_device *pdev, struct
usb_device_info *pinfo);
intlibusb20_dev_get_iface_desc(struct libusb20_device *pdev, uint8_t
iface_index, char *buf, uint8_t len);
diff --git a/lib/libusb/libusb20_int.h b/lib/libusb/libusb20_int.h
index 0251c5f..6705c63 100644
--- a/lib/libusb/libusb20_int.h
+++ b/lib/libusb/libusb20_int.h
@@ -105,6 +105,7 @@ typedef int (libusb20_process_t)(struct libusb20_device
*pdev);
typedef int (libusb20_reset_device_t)(struct libusb20_device *pdev);
typedef int (libusb20_set_power_mode_t)(struct libusb20_device *pdev, uint8_t
power_mode);
typedef int (libusb20_get_power_mode_t)(struct libusb20_device *pdev, uint8_t
*power_mode);
+typedef int (libusb20_get_power_usage_t)(struct libusb20_device *pdev,
uint16_t *power_usage);
typedef int (libusb20_set_alt_index_t)(struct libusb20_device *pdev, uint8_t
iface_index, uint8_t alt_index);
typedef int (libusb20_set_config_index_t)(struct libusb20_device *pdev,
uint8_t index);
typedef int (libusb20_check_connected_t)(struct libusb20_device *pdev);
@@ -127,6 +128,7 @@ typedef void (libusb20_tr_cancel_async_t)(struct
libusb20_transfer *xfer);
m(n, check_connected) \
m(n, set_power_mode) \
m(n, get_power_mode) \
+ m(n, get_power_usage) \
m(n, set_alt_index) \
m(n, set_config_index) \
m(n, tr_cancel_async)