LINUX.ORG.RU

Linux: программно «дернуть» USB-устройство


0

0

Есть некое USB-устройство, подключенное к некому Linux-устройству на процессоре MIPS. Ядро 2.4.30. Время от времени возникает ситуация, что USB-устройство выходит из-под контроля. Пока есть два способа бороться с этим:

1) Выдернуть и снова вставить USB-устройство

2) Дернуть питание Linux-устройства

Оба способа плохи тем, что требуется кто-то для выполнения этих операций. Что характерно, ребут Linux-устройства не помогает, USB-устройство продлжает жить своей жизнью после ребута (потому что питание не снимается). Оно прекрасно обнаруживается системой, но воспользоваться я им не могу. Я думал, что если выдернуть из ядра модуль USB-контроллера, то USB-устройство вернется в исходное состояние. Не тут то было!

usb.c: USB disconnect on device 01:03.2-1 address 2

Но устройство все еще живет само по себе!

Вопрос: если я делаю USB disconnect таким образом, устройство вообще должно об этом знать? Может ли оно увидеть как-то, что со стороны хоста USB-контроллера как-бы больше нет?

И вообще, что бы мне предпринять в этой ситуации?

Deleted

>2) Дернуть питание Linux-устройства

Если устройство поддерживает, то можно попробовать /sys/bus/usb/devices/${device}/power/level

YAR ★★★★★ ()

Какой SoC & какой USB контролер?

anonymous ()

Есть чудная программка usbreset. Мне с некоторыми устройствами помагала.

/* 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;
}

vga ★★ ()

Девайс может зависать на своем аппаратном уровне, а usb устроен так, что на нем всегда есть 5 вольт. Передергивание модулей ядра тут ничего не даст.

Можно попробовать что-то вроде:

echo suspend > /sys/bus/usb/devices/1-1/power/level &&
sleep 10 &&
echo auto > /sys/bus/usb/devices/1-1/power/level

Deleted ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.