Looking for Computer Science  & Information Technology online courses ?
Check my new web site: https://www.yesik.it !

Sur un ordinateur récent doté d'un port USB3.0, vous risquez de rencontrez des problèmes lors de la mise en hibernation sur disque de votre système Linux.

La raison en est que le driver xhci – chargé de la prise en charge du protocole USB3.0 – ne supporte par encore à ce jour (mars 2011) les opérations de mise en veille/reprise (suspend/resume).

Symptômes et expérimentations

Sous Debian Squeeze, le message d'erreur symptomatique est le suivant lors d'une tentative d'hibernation du système:

Suspending console(s) (use no_console_suspend to debug)
pm_op(): usb_dev_freeze+0x0/0x10 returns -2
PM: Device usb3 failed to freeze: error -2

Une solution est de décharger le module xhci du noyau avant d'entrer en hibernation:

sh# modprobe -r xhci

Si cette solution manuelle n'est pas très pratique, elle permet au moins de vérifier que ce driver est bien la cause du problème. Une fois xhci déchargé, l'hibernation devrait se faire. Par contre, la tentative de réveil du système devrait échouer avec ce message:

Device usb3 failed to quiesce: error -2

En effet, lors de la reprise du système, avant le chargement de l'image, le driver sera rechargé par le système. Et il refusera tout autant de se mettre en veille pour recharger l'image. Après ces quelques tests, il est temps de trouver une solution plus pérenne...

Solution 1: blacklister xhci

Si vous n'avez pas besoin des capacités du port USB3.0, la solution la plus simple est de blacklister le module xhci. De cette manière, il ne sera plus chargé, et ne se mettra plus en travers du processus d'hibernation. De plus, pour permettre la reprise du système, si vous utilisez un ramdisk initial pour le boot (c'est le cas sur la plupart des distribution), il vous faudra reconstruire initrd.img:

sh# modprobe -r xhci' # Pour pouvoir tester tout de suite...
sh# echo blacklist xhci >> /etc/modprobe.d/xhci.conf
sh# update-initramfs -u

Dès ces modifications effectuées, vous devriez pouvoir mettre en veille sur disque votre système. Et le ressortir d'hibernation.

Solution 2: Utiliser un script d'action automatique à l'hibernation

Si vous utilisez les fonctionnalités spécifiques du port USB3.0, s'en priver définitivement n'est pas envisageable. Dans ce cas, il est possible d'utiliser un script pour décharger le driver problématique lors de la mise en veille, et le recharger au réveil de la machine:

sh# cat > /etc/pm/sleep.d/05_xhci << EOF
#!/bin/sh
# Fix USB3 suspend and hibernate problems
case $1 in
  hibernate)
    modprobe -r xhci
    ;;
  suspend)
    modprobe -r xhci
    ;;
  thaw)
    modprobe xhci
    ;;
  resume)
    modprobe xhci
    ;;
  *) echo "USB3 fix script: wrong argument!"
    ;;
esac
EOF
sh# chmod+x /etc/pm/sleep.d/05_xhci

Limitations

Bien que séduisante, cette solution à une sérieuse limitation: elle suppose que le driver xhci peut être déchargé du noyau. Or, ça ne sera pas possible si un périphérique l'utilise encore. Par exemple, si vous avez connecté à votre système un disque dur USB3.0. Dans ce cas, il sera aussi nécessaire de démonter (umount) le disque avant l'hibernation. Ce qui à son tour sera un problème si le disque est en cours d'utilisation au moment ou vous souhaitez mettre votre système en veille…

Références