Включение/выключение питания USB устройств из консоли

Иногда бывают ситуации, когда нужно отключить USB флешку, сделать настройку какой-то программы и потом опять подключить для нормальной работы. Но что делать если эти действия нужно сделать на удаленном сервере, к которому у нас нет физического доступа. Можно обратиться в службу поддержки, но можно и сделать все своими силами «не отходя от кассы». Расскажу как это делается.

Допустим, наша флешка уже втыкнута в USB-порт. Первым делом нужно проверить так ли это.

sasha@sasha-desktop# lsusb
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 002: ID 09da:000a A4 Tech Co., Ltd Port Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 004: ID 090c:1000 Feiya Technology Corp. Flash Drive
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Как видим, USB-флешка находиться на шине Bus 001. Следовательно нам нужно найти в /sys/bus/usb/devices/ соответствующее USB устройство и выключить питание.

sasha@sasha-desktop:~# cd /sys/bus/usb/devices/
sasha@sasha-desktop:/sys/bus/usb/devices# ls
1-0:1.0  1-6  1-6:1.0  2-0:1.0  2-2  2-2:1.0  3-0:1.0  4-0:1.0  5-0:1.0  usb1  usb2  usb3  usb4  usb5

Чтобы копаться в системных устройствах нужны права суперпользователя.

root@sasha-desktop:/sys/bus/usb/devices# cat 1-6/busnum
1
root@sasha-desktop:/sys/bus/usb/devices# cat 2-2/busnum
2

По скольку мы знаем, что наша USB флешка на физической шине с номером 1. Следовательно, нужно отключить питание устройства 1-6, так как именно оно отвечает за первую шину.

root@sasha-desktop:/sys/bus/usb/devices# echo suspend > 1-6/power/level

Приведенная выше команда, отключит питание устройства на лету. Проверим теперь, так ли это.

root@sasha-desktop:/sys/bus/usb/devices# lsusb
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 002: ID 09da:000a A4 Tech Co., Ltd Port Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Как видим — устройство отключено.
После внесения нужных изменений, подключаем питание USB устройства.

root@sasha-desktop:/sys/bus/usb/devices# echo on > 1-6/power/level
root@sasha-desktop:/sys/bus/usb/devices# lsusb
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 002: ID 09da:000a A4 Tech Co., Ltd Port Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 004: ID 090c:1000 Feiya Technology Corp. Flash Drive
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Как видим, все работает.

Литература:
http://www.mjmwired.net/kernel/Documentation/usb/power-management.txt

Автор: admin, 19 мая 2012
Рубрики: Linux
Метки: ,
15 комментариев к сообщению: “Включение/выключение питания USB устройств из консоли”
  1. Алексей:

    Здравствуйте. Попробовал — не получилось. При вводе команды(echo suspend > 1-3/power/level) от суперпользователя «su», выдает «bash: echo: ошибка записи: Недопустимый аргумент» 🙁

    • Здравствуйте. В данном случаи Вам нужно посмотреть включен ли параметр ядра CONFIG_USB_SUSPEND. Если Вы используете Ubuntu:

      root@test-s01:~# grep CONFIG_USB_SUSPEND /boot/config-2.6.32-32-server     
      CONFIG_USB_SUSPEND=y
      
  2. Александр:

    root@ACCKEY:/boot# cat /boot/config-3.2.0-29-generic-pae | grep CONFIG_SUSPEND
    CONFIG_SUSPEND=y
    CONFIG_SUSPEND_FREEZER=y

    При этом из-под рута не дает изменить файл /power/level

  3. Zeka13:

    не работает

    root@Zond:/sys/bus/usb/devices# echo suspend > 2-1/power/level bash: echo: ошибка записи: Недопустимый аргумент
    root@Zond:/sys/bus/usb/devices# grep CONFIG_USB_SUSPEND /boot/config-3.8.0-23-generic
    CONFIG_USB_SUSPEND=y
    root@Zond:/sys/bus/usb/devices#

    • Из документации:
      «In kernels up to 2.6.32, you could also specify «suspend», meaning that the device should remain suspended and autoresume was not allowed. This setting is no longer supported.»
      Так как у Вас ядро 3.8 такой способ не прокатит. Вместо этого нужно сделать так:

      echo "0" > /sys/bus/usb/devices/2-1/power/autosuspend
      echo "auto" > /sys/bus/usb/devices/2-1/power/level
      
  4. А если и такой способ не катит? Кроме того, в этих файлах эти значения по умолчанию. Ядро 3.12.

    • Из документации:
      «Starting with the 3.10 kernel release, dynamic PM support for USB is
      present whenever the kernel was built with CONFIG_PM_RUNTIME enabled.
      The CONFIG_USB_SUSPEND option has been eliminated.»

      В этом случаи вы вообще можете освободить(удалить) USB-устройство и потом снова включить.

      # Смотрим какие есть устройства - находим нашу флешку на Bus 01 --> port 01, значит unbind для 1-1 устройства (может быть Bus01 --> port1 --> port1 - тогда 1-1.1, и т.п.)
      root@ubuntu:~# lsusb -t      
      /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
          |__ Port 1: Dev 2, If 0, Class=HID, Driver=usbhid, 12M
          |__ Port 1: Dev 2, If 1, Class=HID, Driver=usbhid, 12M
          |__ Port 2: Dev 3, If 0, Class=hub, Driver=hub/7p, 12M
      /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M
          |__ Port 1: Dev 2, If 0, Class=stor., Driver=usb-storage, 480M
      
      # Проверяем, что есть такое устройство - /dev/sdb
      root@ubuntu:~# ls -1 /dev/sd*
      /dev/sda
      /dev/sda1
      /dev/sda2
      /dev/sda5
      /dev/sdb
      /dev/sdb1
      
      # Теперь делаем undind (стопаем)
      root@ubuntu:~# echo '1-1' > /sys/bus/usb/drivers/usb/unbind 
      
      # Проверяем что устройство пропало
      root@ubuntu:~# ls -1 /dev/sd*
      /dev/sda
      /dev/sda1
      /dev/sda2
      /dev/sda5
      root@ubuntu:~# lsusb -t      
      1-1: No such file or directory
      /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
          |__ Port 1: Dev 2, If 0, Class=HID, Driver=usbhid, 12M
          |__ Port 1: Dev 2, If 1, Class=HID, Driver=usbhid, 12M
          |__ Port 2: Dev 3, If 0, Class=hub, Driver=hub/7p, 12M
      /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M
      
      # Теперь включаем обратно
      root@ubuntu:~# echo '1-1' > /sys/bus/usb/drivers/usb/bind 
      root@ubuntu:~# lsusb -t      
      /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
          |__ Port 1: Dev 2, If 0, Class=HID, Driver=usbhid, 12M
          |__ Port 1: Dev 2, If 1, Class=HID, Driver=usbhid, 12M
          |__ Port 2: Dev 3, If 0, Class=hub, Driver=hub/7p, 12M
      /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M
          |__ Port 1: Dev 2, If 0, Class=stor., Driver=usb-storage, 480M
      root@ubuntu:~# ls -1 /dev/sd*
      /dev/sda
      /dev/sda1
      /dev/sda2
      /dev/sda5
      /dev/sdb
      /dev/sdb1
      
      • Так то оно так, устроство удаляется. Вот только питание с VBUS не снимается. В результате хардварный резет устройства не происходит.

        • Вообще то как раз таки снимается, потому что система вообще не видит никакого устройства и не может подавать на него питание. Для простой проверки можно подключить USB мышку или же флешку с вечно светящимся диодиком. После unbind/bind ядро будет писать в syslog, что отключили/подключили новое устройство и питание будет выключено/включено, а флешка или мышка будут потухнет/засветиться.

          # Делаем unbind и получаем одну строчку и дохнет лампочка на флешке/мышке 
          Oct 30 01:00:55 ubuntu kernel: [ 1549.307234] usb 1-1: USB disconnect, device number 2
          
          # Делаем bind и все возвращается (только номер устройства теперь будет на 1 больше - 3)  
          Oct 30 01:04:03 ubuntu kernel: [ 1736.766528] usb 1-1: new high-speed USB device number 3 using ehci-pci
          Oct 30 01:04:03 ubuntu kernel: [ 1737.017562] usb 1-1: New USB device found, idVendor=1005, idProduct=b113
          Oct 30 01:04:03 ubuntu kernel: [ 1737.017576] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
          Oct 30 01:04:03 ubuntu kernel: [ 1737.017604] usb 1-1: Product: USB FLASH DRIVE 
          Oct 30 01:04:03 ubuntu kernel: [ 1737.017610] usb 1-1: Manufacturer:         
          Oct 30 01:04:03 ubuntu kernel: [ 1737.017615] usb 1-1: SerialNumber: 19831F3410D6
          Oct 30 01:04:03 ubuntu kernel: [ 1737.034344] usb-storage 1-1:1.0: USB Mass Storage device detected
          Oct 30 01:04:03 ubuntu kernel: [ 1737.038342] scsi8 : usb-storage 1-1:1.0
          Oct 30 01:04:04 ubuntu kernel: [ 1738.094835] scsi 8:0:0:0: Direct-Access              USB FLASH DRIVE  PMAP PQ: 0 ANSI: 0 CCS
          Oct 30 01:04:04 ubuntu kernel: [ 1738.102599] sd 8:0:0:0: Attached scsi generic sg2 type 0
          Oct 30 01:04:04 ubuntu kernel: [ 1738.158247] sd 8:0:0:0: [sdb] 16121856 512-byte logical blocks: (8.25 GB/7.68 GiB)
          Oct 30 01:04:04 ubuntu kernel: [ 1738.188480] sd 8:0:0:0: [sdb] Write Protect is off
          Oct 30 01:04:04 ubuntu kernel: [ 1738.188492] sd 8:0:0:0: [sdb] Mode Sense: 23 00 00 00
          Oct 30 01:04:04 ubuntu kernel: [ 1738.235283] sd 8:0:0:0: [sdb] No Caching mode page found
          Oct 30 01:04:04 ubuntu kernel: [ 1738.235334] sd 8:0:0:0: [sdb] Assuming drive cache: write through
          Oct 30 01:04:04 ubuntu kernel: [ 1738.501046] sd 8:0:0:0: [sdb] No Caching mode page found
          Oct 30 01:04:04 ubuntu kernel: [ 1738.501163] sd 8:0:0:0: [sdb] Assuming drive cache: write through
          Oct 30 01:04:05 ubuntu kernel: [ 1738.563731]  sdb: sdb1
          Oct 30 01:04:05 ubuntu kernel: [ 1738.813468] sd 8:0:0:0: [sdb] No Caching mode page found
          Oct 30 01:04:05 ubuntu kernel: [ 1738.815947] sd 8:0:0:0: [sdb] Assuming drive cache: write through
          Oct 30 01:04:05 ubuntu kernel: [ 1738.818371] sd 8:0:0:0: [sdb] Attached SCSI removable disk
          
  5. Alexander:

    Для ядра 3.8 приведены команды включения/отключения или обе эти команды для отключения питания?

    • Обе для выключения. Т.е. мы ставим автоматическое отключения питания (auto in ../power/level) если устройство нигде не используется (т.е. устройство в idle состоянии). Чтобы вручную задать состояние idle, нужно впихнуть «0» в ../power/autosuspend

      «When the counter is > 0 then the interface is deemed to be busy, and the kernel will not
      autosuspend the interface’s device. When the usage counter is = 0 then the interface is
      considered to be idle, and the kernel may autosuspend the device.»

  6. Alx:

    USB-модем хорошо передёргивает в 4.9
    echo ‘1-4’ > /sys/bus/usb/drivers/usb/unbind && echo ‘1-4’ > /sys/bus/usb/drivers/usb/bind

Написать комментарий

Последние статьи

Яндекс.Метрика
?>