Bilgisayardan fiziksel olarak bağlantıyı kesmeden/bağlanmadan bir USB aygıtının bağlantısını sıfırlamak mümkün müdür?
Özellikle benim cihazım bir dijital fotoğraf makinesi. gphoto2' kullanıyorum, ancak son zamanlarda "device read errors" alıyorum, bu yüzden bağlantıyı yazılımsal olarak sıfırlamayı denemek istiyorum.
Anladığım kadarıyla, kamera için yüklenen herhangi bir çekirdek modülü yok. İlgili görünen tek modül usbhid
.
Aşağıdakileri usbreset.c
olarak kaydedin
/* usbreset -- send a USB port reset to a USB device */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
int main(int argc, char **argv)
{
const char *filename;
int fd;
int rc;
if (argc != 2) {
fprintf(stderr, "Usage: usbreset device-filename\n");
return 1;
}
filename = argv[1];
fd = open(filename, O_WRONLY);
if (fd < 0) {
perror("Error opening output file");
return 1;
}
printf("Resetting USB device %s\n", filename);
rc = ioctl(fd, USBDEVFS_RESET, 0);
if (rc < 0) {
perror("Error in ioctl");
return 1;
}
printf("Reset successful\n");
close(fd);
return 0;
}
Aşağıdaki komutları terminalde çalıştırın:
Programı derleyin:
$ cc usbreset.c -o usbreset
Sıfırlamak istediğiniz USB cihazının Veri Yolu ve Cihaz Kimliğini alın:
$ lsusb
Bus 002 Cihaz 003: ID 0fe9:9010 DVICO
Derlenmiş programımızı çalıştırılabilir hale getirin:
$ chmod +x usbreset
Programı sudo yetkisi ile çalıştırın; lsusb
komutunu çalıştırarak bulunan <Bus>
ve <Device>
id'leri için gerekli değişiklikleri yapın:
$ sudo ./usbreset /dev/bus/usb/002/003
Yukarıdaki programın kaynağı: http://marc.info/?l=linux-usb&m=121459435621262&w=2
Daha önce sizin özel durumunuzla karşılaşmadım, bu yüzden yeterli olup olmayacağından emin değilim, ancak bir USB aygıtını sıfırlamak için bulduğum en basit yol bu komuttur: (Harici uygulamalara gerek yok)
sudo sh -c "echo 0 > /sys/bus/usb/devices/1-4.6/authorized"
sudo sh -c "echo 1 > /sys/bus/usb/devices/1-4.6/authorized"
Libfreenect'in onu tekrar uykuya almak için bir API'si yok gibi göründüğünden, Kinect'imi sıfırlamak için kullandığım asıl şey bu. Bu benim Gentoo kutumda, ama çekirdek sysfs için aynı yol yapısını kullanacak kadar yeni olmalı.
Sizinkinin 1-4.6
olmayacağı açıktır, ancak bu aygıt yolunu çekirdek günlüğünüzden (dmesg
) çekebilir veya satıcı ve ürün kimliklerini almak için lsusb
gibi bir şey kullanabilir ve ardından yolların farklı satıcı / ürün kimliği çiftleriyle nasıl ilişkili olduğunu listelemek için bunun gibi hızlı bir komut kullanabilirsiniz:
for X in /sys/bus/usb/devices/*; do
echo "$X"
cat "$X/idVendor" 2>/dev/null
cat "$X/idProduct" 2>/dev/null
echo
done
Bu, bağlı tüm USB1/2/3 bağlantı noktalarını sıfırlayacaktır[1]:
for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
[ -e "$i" ] || continue
echo "${i##*/}" > "${i%/*}/unbind"
echo "${i##*/}" > "${i%/*}/bind"
done
Bunun sorununuzu çözeceğine inanıyorum. Tüm USB uç noktalarını sıfırlamak istemiyorsanız, /sys/bus/pci/drivers/ehci_hcd
den uygun aygıt kimliğini kullanabilirsiniz
Notlar:
[1]: *hci_hcd
çekirdek sürücüleri tipik olarak USB bağlantı noktalarını kontrol eder. ohci_hcdve
uhci_hcdUSB1.1 portları içindir,
ehci_hcdUSB2 portları içindir ve
xhci_hcd` USB3 portları içindir. (bkz. https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire))