Вопрос или проблема
У меня проблема с некоторым оборудованием в тестовой лаборатории: когда у тестируемого устройства возникает проблема, кажется, что “сбой” контроллера USB вызывает отсутствие отображения подключенных устройств в порту… однако всё становится хуже. Если сервер, к которому подключено устройство, перезагружается, то он зависает во время POST, потому что контроллер жизненного цикла Dell пытается выполнить перечисление USB портов, и они не отвечают.
Я пробовал несколько вещей, таких как:
- использование
powertop
для попытки изменения состояния порта (не даёт результата) echo 0 > /sys/bus/usb/devices/usb1/bConfigurationValue
, что должно вызывать сброс.- изменение
/sys/bus/usb/devices/usb1/power/wakeup
на включённое и выключенное, что не меняет ситуацию - поиск в документации по ipmitool, чтобы найти способ это сделать.
- использование
modprobe -r usbhid
для удаления модуля ядра usbhid, затем установка его снова
Я также попробовал
root@least-nest:/sys/bus/pci/drivers/ehci-pci# echo -n '0000:00:14.0' > unbind root@least-nest:/sys/bus/pci/drivers/ehci-pci# echo -n '0000:00:14.0' > bind
но получил сообщение
-bash: echo: write error: No such device
Ничто из этого не меняет ситуацию. Кажется, что почти невозможно действительно “сбросить” или выключить USB корневой концентратор/порт. Единственное решение, которое позволяет серверу успешно перезагрузиться, – использовать racadm
для предварительного отключения внутренних USB портов, затем перезагрузить машину, обходя USB перечисление во время POST.
Так как перезагрузка – это кардинальная мера, существует ли другой способ в основном “обновить” или “перезагрузить” USB контроллеры, встроенные в материнскую плату? Я работаю параллельно над поиском проблем с подключённым устройством (например, его удалённое отключение), но основное внимание сейчас уделяется попытке обойти перезагрузку машины.
Следует упомянуть, что операционная система – Ubuntu 18.04 на Dell R630.
Спасибо!
Написал инструмент специально для этой задачи.
Он может сбросить само устройство, концентратор, к которому оно подключено, или все USB порты машины.
Устанавливается с помощью pip install usb_resetter
Использование:
usb_resetter -d 1234:5678 --reset-hub
Где 1234:5678 – это данные VID:PID вашего устройства.
Их можно получить с помощью
usb_resetter --list
Больше документации можно найти на https://github.com/netinvent/usb_resetter
Извините за мой английский, он плохой, поэтому я использую переводчик Google, ха-ха.
Итак, команда, которую вы запускаете, это:
echo 0 > /sys/bus/usb/devices/usb1/bConfigurationValue
Это выключает порт, но затем вам нужно выполнить echo с 1, чтобы снова его включить, и это вызовет своего рода сброс.
По крайней мере, это сработало для меня.
Сообщаю, что я работаю над этим на Redhat 5.1 с ядром 2.6.18, который имеет очень низкий уровень контроля над USB, ядро 2.6.32 уже лучше для этого, а в самых современных версиях Linux имеется намного больше контроля над USB портами.
Надеюсь, это вам поможет, отвечаю немного с опозданием, но, возможно, это поможет другому коллеге.
Привет из Аргентины
Когда у меня были похожие проблемы в аналогичной ситуации, оказалось, что устройство потребляло много энергии, и USB порт на компьютере и концентраторе не мог снабжать его непрерывно.
Я в итоге приобрёл концентратор с внешним питанием, и с тех пор у меня не было заморозок.
Вы можете приобрести устройства онлайн, которые измеряют текущее и напряжение USB порта (в использовании). Я рекомендую вам приобрести одно из таких устройств.
Вот скрипт shell, использующий grep и примитивы shell для поиска пути и сброса USB устройства, когда указаны ID производителя и устройства:
#!/bin/sh
SCANNER_USB_ID_VENDOR="04e8"
SCANNER_USB_ID_DEVICE="3441"
USB_DEVICES_SYS_BASE="/sys/bus/usb/devices"
USB_SYS_FILE_CONFIGURATION="bConfigurationValue"
USB_SYS_FILE_VENDOR="idVendor"
USB_SYS_FILE_DEVICE="idProduct"
USB_SYS_SETTING_OFF=0
USB_SYS_SETTING_ON=1
USB_SYS_SETTING_WAIT=1
USB_SYS_PATH_CONFIGURATION=""
for TEMP_USB_SYS_PATH in "$USB_DEVICES_SYS_BASE"/*
do
if [ -f "$TEMP_USB_SYS_PATH/$USB_SYS_FILE_VENDOR" -a \
-f "$TEMP_USB_SYS_PATH/$USB_SYS_FILE_DEVICE" ]
then
if [ "`cat $TEMP_USB_SYS_PATH/$USB_SYS_FILE_VENDOR`" = "$SCANNER_USB_ID_VENDOR" -a \
"`cat $TEMP_USB_SYS_PATH/$USB_SYS_FILE_DEVICE`" = "$SCANNER_USB_ID_DEVICE" ]
then
USB_SYS_PATH_CONFIGURATION="$TEMP_USB_SYS_PATH/$USB_SYS_FILE_CONFIGURATION"
fi
fi
done
if [ -f "$USB_SYS_PATH_CONFIGURATION" ]
then
echo "$USB_SYS_SETTING_OFF" > "$USB_SYS_PATH_CONFIGURATION"
sleep "$USB_SYS_SETTING_WAIT"
echo "$USB_SYS_SETTING_ON" > "$USB_SYS_PATH_CONFIGURATION"
fi
Сначала вам нужно записать 0 в bConfigurationValue, потом подождать немного, и затем записать 1 в bConfigurationValue
У меня были проблемы с моим принтером Samsung SCX-3205. Он терял возможность сканирования после печати чего-либо, так что мне пришлось написать скрипт для его ручного отключения и включения.
Ответ или решение
Вопрос о том, как перезагрузить или отключить питание USB-порта при возникновении проблем с устройством, представляет собой распространенную проблему в управлении аппаратным обеспечением серверов и рабочих станций. Особенно сложно это становится, когда неправильная работа устройства вызывает зависание контроллера USB, что влияет на загрузку системы из-за зависания во время POST. Рассмотрим возможные решения.
Теория
USB (Universal Serial Bus) — это универсальный интерфейс для подключения периферийных устройств к компьютеру. В его основе лежит схема, предполагающая автоматическую инициализацию и управление подключенными устройствами. Однако, USB устроен так, что в случае перегрузки или неправильной работы устройства может зависнуть контроллер USB, что делает его неотзывчивым к дальнейшему подключению устройств без перезагрузки.
Примеры
-
Перезагрузка порта через интерфейс ОС: В современных системах Linux существуют команды, позволяющие отключить и перезагрузить USB-порт. Например, использование команд в
/sys/bus/usb/devices/
для работы сbConfigurationValue
может временно отключить порт. -
Обновление драйверов: Иногда проблема может быть связана с драйверами. Команды, такие как
modprobe -r usbhid
с последующей перезагрузкой модуля, могут помочь, если проблема связана с драйвером ввода-вывода. -
Использование сторонних инструментов: Инструменты вроде
usb_resetter
позволяют перезагружать контроллеры и устройства, предоставляя более гибкий подход к управлению портами. -
Аппаратные решения: Иногда проблема может быть связана с недостаточной мощностью, предоставляемой портом. Использование внешних USB-концентраторов с питанием может устранить сбои, вызванные нехваткой энергии.
Применение
В вашей ситуации стоит рассмотреть использование всех трех подходов.
-
Командный процесс через терминал:
Для временного отключения и восстановления порта можно использовать последовательность команд:echo 0 > /sys/bus/usb/devices/usb1/bConfigurationValue sleep 1 echo 1 > /sys/bus/usb/devices/usb1/bConfigurationValue
Это должно имитировать "питание" порта и иногда помогает восстановить его работоспособность.
-
Обновление программного обеспечения и использование сторонних инструментов:
Установитеusb_resetter
, который позволит более гибко управлять устройствами через:pip install usb_resetter usb_resetter -d 1234:5678 --reset-hub
Где
1234:5678
— это VID и PID вашего устройства, которые вы можете узнать с помощьюusb_resetter --list
. -
Основные проверки системы и уровня питания:
Если проблема может быть связана с энергопотреблением, целесообразно получить измерительные устройства для проверки параметров USB-портов. Также, следовало бы рассмотреть использование внешних концентраторов с собственным питанием для поддержки мощных устройств.
Заключение
Задача по управлению и диагностики USB-портов может быть сложной, но при условии внедрения правильных техник и инструментов, можно добиться большей стабильности системы без необходимости в перезагрузке сервера. Каждое из предложенных решений следует адаптировать и тестировать в контексте конкретной ситуации и особенностей используемого оборудования. Учитывая, что ваша система работает на Ubuntu 18.04 на серверах Dell R630, эти решения должны способствовать быстрому решению вашей проблемы.