Closed CpServiceSpb closed 2 years ago
Please read FAQ https://github.com/mvp/uhubctl#usb-devices-are-not-removed-after-port-power-down-on-linux. There is not much that uhubctl can do here to fix - it is kernel bug. Consider upgrading to Linux kernel 6.0 when it is released.
I saw it.
But when Linux Kernel 6.0 will be, far away or at least for a while ...
I saw regarding a kernel bug. At the time this works for me: echo 0 > /sys/bus/usb/devices/$DEVICE.$PORT/remove && ./uhubctl -l $DEVICE -p $PORT -a $ONOFF But it is desirable that all these would do ubhubctl. I am not an experienced programmer but I will try to call or move usb_remove_device to ubhubctl to see what will happen. If you can do so, it would be faster and more quality. The function is in hub.c file.
Regards ...
пт, 23 сент. 2022 г. в 07:58, mvp @.***>:
Please read FAQ https://github.com/mvp/uhubctl#usb-devices-are-not-removed-after-port-power-down-on-linux. There is not much that uhubctl can do here to fix - it is kernel bug. Consider upgrading to Linux kernel 6.0 when it is released.
— Reply to this email directly, view it on GitHub https://github.com/mvp/uhubctl/issues/458#issuecomment-1255802611, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD2XQ7BV5DNK3NWOOD2TYKTV7U2INANCNFSM6AAAAAAQTRXRSY . You are receiving this because you authored the thread.Message ID: @.***>
hub.c is kernel file, uhubctl doesn't have access to kernel space.
In general, this is pure cosmetic issue, doesn't affect actual port power state. It has workaround listed in FAQ. Sorry, using sysfs remove will not be added to uhubctl because when I tried doing it a while ago, I couldn't get device file to properly add back. udevadm trigger is the way to do it. Or use kernel which has fixed this bug.
Hi.
So strange. Because echo 0 > /sys/bus/usb/devices/$DEVICE.$PORT/remove called before ubhubctl with off option do all is necessary well. And then , after ubhubctl with on option, the device is correctly appeared on the system.
hub.c is kernel file, uhubctl doesn't have access to kernel space Is usb_remove_device kernel one ?
In general, this is pure cosmetic issue You mean adding usb_remove_device to uhhubctrl, do you ?
doesn't affect the actual port power state In my case the port state is changed. Because my Hub based on Microchip 2517 only (without additional controllers, for example PIC) is constructed to turn on/off both lines: data and vusb (power) but simultaneously, but both lines, not only vusb.. And device plugged to the port is really powered on/off, But, because of, as I think, data line and power line are switched simultaneously, the device' s logical part is still remained on the system. When I simply unplug USB device from the port manually, the first data line is disconnected, then (with very short time) the power line and OS understand that the device is unplugged and remove it from itself. As it is written in a link posted at your FAQ, as I thought ENABLE feature has to be cleared and usb_device_remove had to be called to "clear' device from the system.
In my case, it is necessary to remove the "logical" device - USB device logically presented on the system. Actually I don' t need to turn the port off, it is made well by your soft. And then turned well port on and the device is appeared on the system without troubles and available as well as via lsusb, /dev/ttyUSBX . I need only to remove the logical part of the device from the system during port off.
I suppose that usb_device_remove will do the same as echo 0 > /sys/bus/usb/devices/$DEVICE.$PORT/remove calling does before run your ubhubctl. Or I am wrong. So then how is to do so ?
Regards ...
пт, 23 сент. 2022 г. в 18:35, mvp @.***>:
hub.c is kernel file, uhubctl doesn't have access to kernel space.
In general, this is pure cosmetic issue, doesn't affect actual port power state. It has workaround listed in FAQ. Sorry, using sysfs remove will not be added to uhubctl because when I tried doing it a while ago, I couldn't get device file to properly add back. udevadm trigger is the way to do it. Or use kernel which has fixed this bug.
— Reply to this email directly, view it on GitHub https://github.com/mvp/uhubctl/issues/458#issuecomment-1256368415, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD2XQ7DYGSCI66O2DSQ6AULV7XE5HANCNFSM6AAAAAAQTRXRSY . You are receiving this because you authored the thread.Message ID: @.***>
hub.c
is part of Linux kernel and is not possible to use from user space application like uhubctl.
Again, read FAQ https://github.com/mvp/uhubctl#usb-devices-are-not-removed-after-port-power-down-on-linux
➡️ This is fixed by #450 if you are using Linux kernel 6.0 or later.
After powering down USB port, udev does not get any event, so it keeps the device files around. However, trying to access the device files will lead to an IO error.
This is Linux kernel issue. It may be eventually fixed in kernel, see more discussion here. Basically what happens here is that kernel USB driver knows about power off, but doesn't send notification about it to udev.
You can use this workaround for this issue:
sudo uhubctl -a off -l ${location} -p ${port}
sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
Device file will be removed by udev, but USB device will be still visible in lsusb. Note that path /sys/bus/usb/devices/${location}.${port} will only exist if device was detected on that port. When you turn power back on, device should re-enumerate properly (no need to call udevadm again).
Look at the portion of code:
exactly before rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT) at main function:
if (request == LIBUSB_REQUEST_CLEAR_FEATURE) {
// rc = libusb_control_transfer(devh,.
// LIBUSB_ENDPOINT_IN |
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, // request, USB_PORT_FEAT_ENABLE, port, NULL, 0, USB_CTRL_GET_TIMEOUT);
rc = libusb_control_transfer(devh,
LIBUSB_REQUEST_TYPE_CLASS |
LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_ENABLE, // USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT);
size_t sizepath =
strlen("/sys/bus/usb/devices/") + strlen(hubs[i].location) + strlen(".") + intlen(port) + char path[sizepath]; sprintf (path, "%s%s%s%d%s", "/sys/bus/usb/devices/", hubs[i].location, ".", port, "/remove"); int fd; char d = '1'; fd = open(path, O_WRONLY); if (fd > 0) { write (fd, &d, 1); close(fd); } else { fprintf(stderr, "There is impossible to remove Logical part of turned off device on port %d from the OS port); } }
rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, and so on. Remember, exactly before. If it is after, the device will be repowered on ! All works - lsusb doesn' t show the device, ls /dev as well.
And there is no need to run sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
If you are ready, I can send my version of ubhubctl.c or patch one.
Regards ...
пт, 23 сент. 2022 г. в 23:18, mvp @.***>:
hub.c is part of Linux kernel and is not possible to use from user space application like uhubctl.
Again, read FAQ https://github.com/mvp/uhubctl#usb-devices-are-not-removed-after-port-power-down-on-linux USB devices are not removed after port power down on Linux
➡️ This is fixed by #450 if you are using Linux kernel 6.0 or later.
After powering down USB port, udev does not get any event, so it keeps the device files around. However, trying to access the device files will lead to an IO error.
This is Linux kernel issue. It may be eventually fixed in kernel, see more discussion here. Basically what happens here is that kernel USB driver knows about power off, but doesn't send notification about it to udev.
You can use this workaround for this issue:
sudo uhubctl -a off -l ${location} -p ${port}
sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
Device file will be removed by udev, but USB device will be still visible in lsusb. Note that path /sys/bus/usb/devices/${location}.${port} will only exist if device was detected on that port. When you turn power back on, device should re-enumerate properly (no need to call udevadm again).
— Reply to this email directly, view it on GitHub https://github.com/mvp/uhubctl/issues/458#issuecomment-1256635006, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD2XQ7CCU5WHSG3G2D4SNA3V7YGBHANCNFSM6AAAAAAQTRXRSY . You are receiving this because you authored the thread.Message ID: @.***>
It' s preliminary solution and required additional tests. Nonetheless ...
сб, 24 сент. 2022 г. в 01:39, CpServiceSPb @.***>:
Look at the portion of code:
- somewhere at the beginning: / Get the strlen of integer / int intlen(int integer){ int a; for(a = 1; integer /= 10; a++); return a; }
exactly before rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT) at main function:
if (request == LIBUSB_REQUEST_CLEAR_FEATURE) { // rc = libusb_control_transfer(devh,. // LIBUSB_ENDPOINT_IN |
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, // request, USB_PORT_FEAT_ENABLE, port, NULL, 0, USB_CTRL_GET_TIMEOUT);
rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS |
LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_ENABLE, // USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT);
size_t sizepath =
strlen("/sys/bus/usb/devices/") + strlen(hubs[i].location) + strlen(".") + intlen(port) + char path[sizepath]; sprintf (path, "%s%s%s%d%s", "/sys/bus/usb/devices/", hubs[i].location, ".", port, "/remove"); int fd; char d = '1'; fd = open(path, O_WRONLY); if (fd > 0) { write (fd, &d, 1); close(fd); } else { fprintf(stderr, "There is impossible to remove Logical part of turned off device on port %d from the OS port); } }
rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, and so on. Remember, exactly before. If it is after, the device will be repowered on ! All works - lsusb doesn' t show the device, ls /dev as well.
And there is no need to run sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
If you are ready, I can send my version of ubhubctl.c or patch one.
Regards ...
пт, 23 сент. 2022 г. в 23:18, mvp @.***>:
hub.c is part of Linux kernel and is not possible to use from user space application like uhubctl.
Again, read FAQ https://github.com/mvp/uhubctl#usb-devices-are-not-removed-after-port-power-down-on-linux USB devices are not removed after port power down on Linux
➡️ This is fixed by #450 if you are using Linux kernel 6.0 or later.
After powering down USB port, udev does not get any event, so it keeps the device files around. However, trying to access the device files will lead to an IO error.
This is Linux kernel issue. It may be eventually fixed in kernel, see more discussion here. Basically what happens here is that kernel USB driver knows about power off, but doesn't send notification about it to udev.
You can use this workaround for this issue:
sudo uhubctl -a off -l ${location} -p ${port}
sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
Device file will be removed by udev, but USB device will be still visible in lsusb. Note that path /sys/bus/usb/devices/${location}.${port} will only exist if device was detected on that port. When you turn power back on, device should re-enumerate properly (no need to call udevadm again).
— Reply to this email directly, view it on GitHub https://github.com/mvp/uhubctl/issues/458#issuecomment-1256635006, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD2XQ7CCU5WHSG3G2D4SNA3V7YGBHANCNFSM6AAAAAAQTRXRSY . You are receiving this because you authored the thread.Message ID: @.***>
Of course, some additional headers are necessary.
Regards ...
сб, 24 сент. 2022 г. в 02:03, CpServiceSPb @.***>:
Ohh, sleep_ms(50) is necessary. I changed:
- writing 1 to /sys/....../remove
- sleep_ms(50)
- clear ENABLE_FEAT
- clear POWER_FEAT
Regards ...
сб, 24 сент. 2022 г. в 01:44, CpServiceSPb @.***>:
It' s preliminary solution and required additional tests. Nonetheless ...
сб, 24 сент. 2022 г. в 01:39, CpServiceSPb @.***>:
Look at the portion of code:
- somewhere at the beginning: / Get the strlen of integer / int intlen(int integer){ int a; for(a = 1; integer /= 10; a++); return a; }
exactly before rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT) at main function:
if (request == LIBUSB_REQUEST_CLEAR_FEATURE)
{ // rc = libusb_control_transfer(devh,. // LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, // request, USB_PORT_FEAT_ENABLE, port, NULL, 0, USB_CTRL_GET_TIMEOUT);
rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS |
LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_ENABLE, // USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT);
size_t sizepath =
strlen("/sys/bus/usb/devices/") + strlen(hubs[i].location) + strlen(".") + intlen(port) + char path[sizepath]; sprintf (path, "%s%s%s%d%s", "/sys/bus/usb/devices/", hubs[i].location, ".", port, "/remove"); int fd; char d = '1'; fd = open(path, O_WRONLY); if (fd > 0) { write (fd, &d, 1); close(fd); } else { fprintf(stderr, "There is impossible to remove Logical part of turned off device on port %d from the OS port); } }
rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, and so on. Remember, exactly before. If it is after, the device will be repowered on ! All works - lsusb doesn' t show the device, ls /dev as well.
And there is no need to run sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
If you are ready, I can send my version of ubhubctl.c or patch one.
Regards ...
пт, 23 сент. 2022 г. в 23:18, mvp @.***>:
hub.c is part of Linux kernel and is not possible to use from user space application like uhubctl.
Again, read FAQ https://github.com/mvp/uhubctl#usb-devices-are-not-removed-after-port-power-down-on-linux USB devices are not removed after port power down on Linux
➡️ This is fixed by #450 if you are using Linux kernel 6.0 or later.
After powering down USB port, udev does not get any event, so it keeps the device files around. However, trying to access the device files will lead to an IO error.
This is Linux kernel issue. It may be eventually fixed in kernel, see more discussion here. Basically what happens here is that kernel USB driver knows about power off, but doesn't send notification about it to udev.
You can use this workaround for this issue:
sudo uhubctl -a off -l ${location} -p ${port}
sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
Device file will be removed by udev, but USB device will be still visible in lsusb. Note that path /sys/bus/usb/devices/${location}.${port} will only exist if device was detected on that port. When you turn power back on, device should re-enumerate properly (no need to call udevadm again).
— Reply to this email directly, view it on GitHub https://github.com/mvp/uhubctl/issues/458#issuecomment-1256635006, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD2XQ7CCU5WHSG3G2D4SNA3V7YGBHANCNFSM6AAAAAAQTRXRSY . You are receiving this because you authored the thread.Message ID: @.***>
I do not believe your approach is going to work. I tried it more than a year ago, I couldn't make it work and most importantly allow to both disable and then enable the same port without any ill effects.
That said, if you could submit pull request with code that actually compiles and works, it would be helpful to continue this conversation.
Unfortunately, it works. :)) For me, ub the case. As I wrote, my hub is based on Microchip 2517 and there are power line on 1 port only and data with power lines switched on 6 ports but without delay.
And there is one potential thing which is required to think, regarding ubhubctl. If POWER FEATURE is sent but without success, we have already removed "logical" part of a device from the system. At the time, if POWER FEATURE is sent before removing the "logical" part of a device, this is more logical, in the case a device is replugged and the port is turned on on its own. Why, I don' t understand by now.
Regards ...
сб, 24 сент. 2022 г. в 02:33, mvp @.***>:
I do not believe your approach is going to work. I tried it more than a year ago, I couldn't make it work and most importantly allow to both disable and then enable the same port without any I'll effects.
That said, if you could submit pull request with code that actually compiles and works, it would be helpful to continue this conversation.
— Reply to this email directly, view it on GitHub https://github.com/mvp/uhubctl/issues/458#issuecomment-1256796268, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD2XQ7GPMF6TS33SKCMJQBLV7Y44DANCNFSM6AAAAAAQTRXRSY . You are receiving this because you authored the thread.Message ID: @.***>
Ohh, sleep_ms(50) is necessary. I changed:
Regards ...
сб, 24 сент. 2022 г. в 01:44, CpServiceSPb @.***>:
It' s preliminary solution and required additional tests. Nonetheless ...
сб, 24 сент. 2022 г. в 01:39, CpServiceSPb @.***>:
Look at the portion of code:
- somewhere at the beginning: / Get the strlen of integer / int intlen(int integer){ int a; for(a = 1; integer /= 10; a++); return a; }
exactly before rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT) at main function:
if (request == LIBUSB_REQUEST_CLEAR_FEATURE) { // rc = libusb_control_transfer(devh,. // LIBUSB_ENDPOINT_IN |
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, // request, USB_PORT_FEAT_ENABLE, port, NULL, 0, USB_CTRL_GET_TIMEOUT);
rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS |
LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_ENABLE, // USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT);
size_t sizepath =
strlen("/sys/bus/usb/devices/") + strlen(hubs[i].location) + strlen(".") + intlen(port) + char path[sizepath]; sprintf (path, "%s%s%s%d%s", "/sys/bus/usb/devices/", hubs[i].location, ".", port, "/remove"); int fd; char d = '1'; fd = open(path, O_WRONLY); if (fd > 0) { write (fd, &d, 1); close(fd); } else { fprintf(stderr, "There is impossible to remove Logical part of turned off device on port %d from the OS port); } }
rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, and so on. Remember, exactly before. If it is after, the device will be repowered on ! All works - lsusb doesn' t show the device, ls /dev as well.
And there is no need to run sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
If you are ready, I can send my version of ubhubctl.c or patch one.
Regards ...
пт, 23 сент. 2022 г. в 23:18, mvp @.***>:
hub.c is part of Linux kernel and is not possible to use from user space application like uhubctl.
Again, read FAQ https://github.com/mvp/uhubctl#usb-devices-are-not-removed-after-port-power-down-on-linux USB devices are not removed after port power down on Linux
➡️ This is fixed by #450 if you are using Linux kernel 6.0 or later.
After powering down USB port, udev does not get any event, so it keeps the device files around. However, trying to access the device files will lead to an IO error.
This is Linux kernel issue. It may be eventually fixed in kernel, see more discussion here. Basically what happens here is that kernel USB driver knows about power off, but doesn't send notification about it to udev.
You can use this workaround for this issue:
sudo uhubctl -a off -l ${location} -p ${port}
sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
Device file will be removed by udev, but USB device will be still visible in lsusb. Note that path /sys/bus/usb/devices/${location}.${port} will only exist if device was detected on that port. When you turn power back on, device should re-enumerate properly (no need to call udevadm again).
— Reply to this email directly, view it on GitHub https://github.com/mvp/uhubctl/issues/458#issuecomment-1256635006, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD2XQ7CCU5WHSG3G2D4SNA3V7YGBHANCNFSM6AAAAAAQTRXRSY . You are receiving this because you authored the thread.Message ID: @.***>
Hi. First of all, thanks for you soft !
I use USB Hub based on Microchip 2517 with Ubuntu 18.04 LTS x63 with kernel 5.4.0-126. And I have the same issue - that is a device on powered off port of the hub is still "remained" on the system. I mean the virtual part of it. As I saw at there is clearing ENABLE feature of the port and calling usb_remove_device(). I offer to add these steps to the main code of uhubctl. First part I think will be as a follows:
if (request == LIBUSB_REQUEST_CLEAR_FEATURE) { rc = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, request, USB_PORT_FEAT_ENABLE, // USB_PORT_FEAT_POWER, port, NULL, 0, USB_CTRL_GET_TIMEOUT); }
And then add usb_remove_device(). At he time I don' t know how is to do so, I included usb.h but there is no effect.By the way, there is no the issue when USB device is unplugged manually. Why ??