61 votes

Linux USB : mise sous tension et hors tension ?

Comment puis-je activer et désactiver par programmation l'alimentation d'un port USB particulier sous Linux ? Est-ce que c'est possible ? Les réponses pour Mac sont également appréciées !

J'essayais d'avoir un BOC (ne prétendez pas que vous n'avez pas essayé d'en avoir un aussi !) et j'ai fini par en avoir un, et j'aimerais l'utiliser en le connectant au moniteur de notre serveur.

2 votes

Pardonnez mon ignorance, mais, BOC ?

0 votes

@JonHadley, BOC = Woot Bag of Crap. fr.wikipedia.org/wiki/Woot#Bag_of_Crap . Cherchez-le sur youtube pour des déballages très divertissants. J'essaie à chaque fois et je n'en ai pas eu un seul !

3 votes

La réponse semble être une mine d'informations sur la gestion de l'alimentation USB - premier résultat Google pour ganged power switching (sans guillemets).

24voto

mixonic Points 1981

Il y a une entrée sys pour cela dans Linux. À partir de Documentation/usb/power-management.txt :

puissance/niveau

This file contains one of three words: "on", "auto",
or "suspend".  You can write those words to the file
to change the device's setting.

"on" means that the device should be resumed and
autosuspend is not allowed.  (Of course, system
suspends are still allowed.)

"auto" is the normal state in which the kernel is
allowed to autosuspend and autoresume the device.

"suspend" means that the device should remain
suspended, and autoresume is not allowed.  (But remote
wakeup may still be allowed, since it is controlled
separately by the power/wakeup attribute.)

Quelque chose comme : echo on > /sys/bus/usb/devices/usb5/power/level

Vous devrez peut-être aussi jouer avec le paramètre de suspension automatique. Sans demander au noyau d'arrêter d'essayer, il peut suspendre le port automatiquement.

Bonne chance !

0 votes

D'après ma lecture des spécifications de l'USB 2.0, les rails d'alimentation du port USB sont toujours disponibles. Un dispositif connecté au port doit limiter sa consommation d'énergie à 500uA pour une faible puissance et à 2,5mA pour une puissance élevée (normalement des dispositifs de charge de 5 unités). La suggestion de contrôler l'alimentation par le biais d'un hub semble avoir plus de chances de réussir, en supposant que le hub permette de désactiver la sortie d'alimentation.

2 votes

Depuis le noyau v2.6.32, l'option de suspension a été supprimée - voir la documentation liée dans cette réponse.

14voto

L'interaction usbfs semble avoir changé un certain nombre de fois depuis la réponse initiale à cette question. Donc, voici comment je cycle l'alimentation du port du hub sur Ubuntu Oneiric Ocelot à partir d'un shell Bash.

Recherchez le numéro du bus et du périphérique :

sudo lsusb -v|less

Localisez le périphérique dans la hiérarchie des ports du bus / hub en utilisant le numéro du bus et du périphérique :

sudo lsusb -t|less

La syntaxe semble être "bus-port.port.port.port.port.port...". Par exemple, ma souris est connectée à un hub externe qui se connecte au hub de mon ordinateur qui se connecte en interne à un hub Root :

/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/6p, 480M
        |__ Port 1: Dev 3, If 0, Class=hub, Driver=hub/3p, 480M
            |__ Port 1: Dev 6, If 0, Class=HID, Driver=usbhid, 1.5M

Donc, '2-1.1.1' dans le cas ci-dessus. Enfin, coupez l'alimentation du port :

echo '2-1.1.1'|sudo tee /sys/bus/usb/drivers/usb/unbind
sleep 1
echo '2-1.1.1'|sudo tee /sys/bus/usb/drivers/usb/bind

Je n'ai pas branché d'analyseur de protocole pour voir ce qui se passe réellement sur le bus, mais je sais que la lumière de ma souris s'éteint lorsque je la libère. Je suppose qu'au niveau de la couche inférieure, il y a une interaction avec le contrôleur hôte EHCI pour couper l'alimentation sur le port. C'est particulièrement utile pour les périphériques intégrés, comme les webcams UVC, qui ne semblent jamais fonctionner correctement et qui nécessiteraient autrement un redémarrage du système pour être réinitialisés.

Voir aussi le udevadm commandement.

0 votes

Quel moyeu utilisez-vous ? Je suis actuellement à la recherche d'un hub avec une fonctionnalité de contrôle par port, mais cela ne semble pas du tout être annoncé comme une fonctionnalité (sauf par les fabricants de chipset).

0 votes

@Kristian veuillez voir mon commentaire ci-dessous. Il n'a pas sa place ici.

0 votes

Voir aussi ici pour quelques notes sur l'utilisation de udevadm.

8voto

Savant Degrees Points 136

Fouiller dans les signets

http://blog.andrew.net.au/2009/01/01#usb_power_control

Il semble que vous deviez le connecter à un hub et contrôler l'alimentation de ce dernier. Aucun des hubs Root que j'ai vus ne semble pouvoir prendre en charge le contrôle de l'alimentation.

1 votes

Ce n'était pas vrai en 2009, et ce n'est pas vrai maintenant. Consultez cette liste de périphériques USB qui permettent de contrôler la puissance par port : github.com/mvp/uhubctl#compatible-usb-hubs

4voto

@Kristian Typiquement, vous ne trouverez pas de publicité pour les ports contrôlés par logiciel car les utilisateurs ne devraient pas être conscients de cette couche. Je ne pense pas qu'il y ait beaucoup de cas d'utilisation pour cela, si ce n'est pour forcer les appareils alimentés par le bus qui se comportent mal à se mettre dans un état connu, et pour gérer les appareils muets qui utilisent uniquement l'USB pour l'alimentation. Peut-être que le dispositif de Mark tombe dans cette dernière catégorie. C'est un mécanisme rudimentaire de dernier recours.

Comme je l'ai mentionné, je n'ai pas examiné les détails de l'implémentation du hack de débridage et je l'ai seulement essayé sur le contrôleur hôte EHCI intégré dans ma carte mère, un "Intel Corporation 6 Series/C200 Series Chipset Family USB Enhanced Host Controller (rev 05)". Je suppose que ce contrôleur hôte a le bit PPC de HCSPARAMS activé, indiquant le contrôle logiciel des interrupteurs d'alimentation du port, selon la spécification EHCI.

Si vous vous connectez à un concentrateur externe, "un concentrateur indique s'il prend en charge ou non la commutation de l'alimentation par le réglage du champ Logical Power Switching Mode dans wHubCharacteristics", selon la spécification USB 2.0. Je ne me souviens pas si les tests de conformité garantissent cette fonctionnalité ou non, mais si c'est le cas, il suffit de trouver un hub avec le logo USB 2.0. Je suppose que le piratage enverrait une demande de fonctionnalité de port défini, mais il pourrait cycler plus que le port cible. Encore une fois, selon les spécifications de l'USB 2.0, "un hub avec des interrupteurs d'alimentation peut commuter l'alimentation vers tous les ports en tant que groupe/groupe, vers chaque port individuellement, ou avoir un nombre arbitraire de groupes d'un ou plusieurs ports." Je ne suis pas sûr qu'il existe un outil en ligne de commande pour obtenir wHubCharacteristics.

En bref, il n'existe pas, à ma connaissance, de méthode générique efficace pour traiter ce problème. Cependant, il est possible d'interroger un hub interne ou externe pour déterminer son niveau de support et ensuite, s'il est supporté, l'utiliser. Il s'agit juste de savoir combien de temps vous voulez passer à le faire.

0 votes

Il convient de mentionner qu'il existe un certain nombre de hubs qui déclarent prendre en charge cette fonctionnalité, alors qu'ils ne le font pas réellement. Donc malheureusement, exécuter "sudo lsusb -v" pour vérifier wHubCharacteristics ne garantit pas le support réel. Voici la dernière liste des hubs usb qui supportent réellement cette fonctionnalité. gniibe.org/development/ac-power-control-by-USB-hub/index.html Il date de 2011, mais c'est le dernier que j'ai trouvé...

4voto

RVF16 Points 31

Voici un exemple avec une souris sans fil USB Logitech sous linux.

Lisez le paragraphe pertinent de "/proc/bus/usb/devices" en fonction de vos périphériques "Vendor" (identifiant du vendeur) et "ProdID" (identifiant du produit) ou "Manufacturer" et "Product" (toutes ces valeurs sont constantes pour chaque appareil).

cat /proc/bus/usb/devices

(premier paragraphe avec l'appareil sous tension, deuxième paragraphe avec le même appareil hors tension mais toujours branché)

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=1.5 MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c50e Rev=25.10
S:  Manufacturer=Logitech
S:  Product=USB RECEIVER
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 70mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=1.5 MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c50e Rev=25.10
S:  Manufacturer=Logitech
S:  Product=USB RECEIVER
C:  #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 70mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms

Vous avez besoin de deux variables ici. Elles sont situées dans la ligne "T :" (première ligne du paragraphe). Ces variables sont : Bus (Bus=01 dans cet exemple) Cnt (Cnt=01 dans cet exemple)

Vous devrez ajouter "1" (un arithmétique) à "Cnt" pour obtenir le rang Rank=Cnt+1 (c'est une fonction mathématique, Rank=2 dans cet exemple)

Donc le dispositif que vous recherchez est la chaîne suivante : Bus-Rank (ce n'est pas une fonction mathématique, c'est une chaîne, 1-2 dans cet exemple)

Pensez aussi au "C : Ligne " ". Elle contient des informations sur la puissance (courant) de l'appareil. S'il y a un astérisque dans "C : " (comme dans notre 1er exemple) alors l'appareil est sous tension. Si ce n'est pas le cas (" C : "), alors l'appareil est " plus ou moins " hors tension, ce qui signifie qu'il y a toujours un petit courant lorsqu'un appareil est branché, sinon nous ne serions pas en mesure de lire toutes ces informations.

Attention enfin à la ligne "I :". Si le champ "I:*" contient un astérisque (comme dans notre 1er exemple), alors il y a une entrée, depuis ou vers l'appareil, je ne suis pas sûr, peut-être les deux. Le champ de la dernière ligne contient le pilote utilisé ("usbhid" dans notre 1er exemple).

Nous sommes prêts à mettre notre appareil sous tension :

éteindre

echo -n "Bus-Rank" > /sys/bus/usb/drivers/usb/unbind
echo -n "1-2" > /sys/bus/usb/drivers/usb/unbind (in our example)

mise en marche

echo -n "Bus-Rank" > /sys/bus/usb/drivers/usb/bind
echo -n "1-2" > /sys/bus/usb/drivers/usb/bind (in our example)

Ce qui suit est un simple bash script "USBMS" (USB Mouse Switch) qui contrôle la puissance du dispositif dans notre exemple ci-dessus. Il n'est pas très dynamique et il utilise les constantes "Product" et "Manufacturer" pour localiser le paragraphe pertinent de "/proc/bus/usb/devices". Vous devriez plutôt utiliser les constantes "Vendor" (identifiant du fournisseur) et "ProdID" (identifiant du produit). Il vérifie également l'état d'alimentation du périphérique. Exécuter en tant que super-utilisateur.

Commande : ./USBMS action

paramètre : action = "off" ou "0" pour mettre hors tension - action = "on" ou "1" pour mettre sous tension (sans les guillemets)

#!/bin/bash

     USBmouseProduct="USB RECEIVER"
USBmouseManufacturer="Logitech"

              signal=$1

nr3=$(awk '/Product='"$USBmouseProduct"'/ {print NR}' /proc/bus/usb/devices)
nr3=$(expr $nr3 + 0)
nr2=$(awk '/Manufacturer='"$USBmouseManufacturer"'/ {print NR}' /proc/bus/usb/devices)
nr2=$(expr $nr2 + 0)
nr1=$(expr $nr2 - 3)
nr4=$(expr $nr3 + 1)
nrdiff=$(expr $nr3 - $nr2)

[ $nr3 != 0 -a $nr2 != 0 -a $nrdiff = 1 ] && (
                                                 usbmbus0=$(awk 'NR=='$nr1' {print $2}' /proc/bus/usb/devices | awk -F= '{print $2}')
                                                  usbmbus=$(expr $usbmbus0 + 0)
                                                  usbmdev=$(awk 'NR=='$nr1' {print $8}' /proc/bus/usb/devices)
                                                 usbmrank=$(awk 'NR=='$nr1' {print $5}' /proc/bus/usb/devices | awk -F= '{print $2}')
                                                 usbmrank=$(expr $usbmrank + 1)
                                               usbmbusrank="$usbmbus""-""$usbmrank"
                                                usbmpower=$(awk 'NR=='$nr4' {if ( $1=="C:" ) {print 0}; if ( $1=="C:*" ) {print 1}}' /proc/bus/usb/devices)

                                               case $signal in
                                                              off|0)
                                                                    [ $usbmpower = 1 ] && echo -n "$usbmbusrank" > /sys/bus/usb/drivers/usb/unbind
                                                                    ;;
                                                               on|1)
                                                                    [ $usbmpower = 0 ] && echo -n "$usbmbusrank" > /sys/bus/usb/drivers/usb/bind
                                                                    ;;
                                               esac
                                             )

1 votes

@RVF16, il semble qu'il n'y a pas de /proc/bus/usb/devices dans ma version Unbutu 11... existe-t-il une autre approche pour obtenir le "Bus-Rank" d'un périphérique usb ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X