fedora-gaming.webp

Versión revisada y mejorada del post original: Controles de Xbox en Fedora Linux

Normalmente, los Xbox Controllers (en mi caso, Xbox Core Wireless Gaming Controller — quizás lo actualice en el futuro) funcionan de inmediato. Sin embargo, si por alguna razón no funciona, sigue leyendo.

En mi caso, el Xbox Controller funcionaba con normalidad y dejó de funcionar después de una actualización mayor del sistema. El SO podía detectar el dispositivo (udevadm monitor mostraba la conexión) pero Steam no reconocía ninguna entrada del Controller.



Detectando el Problema

  1. El controller se empareja correctamente vía Bluetooth o se conecta vía USB.
  2. El kernel detecta el dispositivo conectándose y desconectándose (vía udevadm monitor).
  3. Steam no muestra ninguna entrada del controller en absoluto.


Cómo Linux Maneja los Xbox Controllers

Como todo en Linux, todo se maneja a través de varias capas.


El Linux Input Stack

Cuando conectas un controller a un sistema Linux, la entrada pasa por varios subsistemas antes de llegar al juego. Esto es lo que sucede:

  • El dispositivo controller se conecta a través de una capa de transporte (USB o Bluetooth)
  • El kernel carga el driver module (kernel module) apropiado para ese tipo específico de dispositivo.
  • El driver traduce los datos crudos del dispositivo en eventos de entrada estándar de Linux, que se exponen a través de nodos de dispositivo en /dev/input.
  • Aplicaciones como Steam leen esos nodos de dispositivo y pasan los datos a los juegos.

Si alguna de estas capas falla (driver faltante, permisos incorrectos, reglas udev faltantes, etc.) el controller no funcionará, incluso si es detectado por el kernel.


Conexiones USB vs Bluetooth

El driver que usa tu Xbox controller depende de cómo lo conectes, esto es importante al saber dónde buscar cuando estás solucionando problemas.

  • Las conexiones USB usan el xpad kernel module (parte del paquete kernel-modules-extra en Fedora). Este es el driver del kernel de Linux in-tree escrito específicamente para Xbox controllers conectados por USB y maneja Xbox, Xbox 360, Xbox One y Xbox Series controllers cuando se conectan vía USB.
  • Las conexiones Bluetooth no usan xpad, en su lugar usan el perfil estándar Bluetooth HID. El kernel maneja esto a través del driver hid-generic (o el driver de terceros hid-xpadneo si está instalado).
  • Xbox Wireless Adapter (Wi-Fi Direct) es una tercera opción. El Xbox Wireless Adapter propietario usa Wi-Fi Direct, no Bluetooth, y requiere el driver xone (disponible aquí) o el antiguo daemon xow.

El Input Event Pipeline

Una vez que el driver correcto se carga y procesa los datos crudos del dispositivo, el kernel expone el controller en /dev/input/:

  • La legacy Joystick API crea dispositivos /dev/input/jsX. Esta es la interfaz antigua. Algunos juegos y herramientas más viejos aún la usan, pero proporciona menos información sobre botones y ejes disponibles.
  • La evdev API crea dispositivos /dev/input/eventX. Esta es la interfaz moderna. Proporciona más información (estados de botones, valores de ejes, force feedback) y es lo que la mayoría de los juegos modernos esperan.

Puedes ver ambos nodos de dispositivo para un controller conectado:

ls -la /dev/input/by-id/ | grep -i xbox

# Legacy Joystick API:
# usb-Microsoft_Controller_XXXX-joystick -> ../js0
# evdev API:
# usb-Microsoft_Controller_XXXX-event-joystick -> ../event16

Ambas interfaces se crean desde el mismo driver. Si ninguna existe, el driver no se cargó. Si solo una existe, algo está parcialmente roto. Si ambas existen pero tu juego no detecta nada, el problema podría ser reglas udev o la configuración de entrada de la aplicación.



Por Qué las Actualizaciones de Fedora Rompen el Soporte de Xbox Controller

Empaquetado de Kernel Modules en Fedora

Fedora divide los kernel modules en múltiples paquetes.

Los paquetes base kernel y kernel-modules contienen módulos necesarios para el hardware más común (controladores de almacenamiento, adaptadores de red, sistemas de archivos, drivers de pantalla), mientras que el paquete kernel-modules-extra contiene módulos opcionales para hardware menos común, como xpad.

Cada versión del kernel tiene su propio paquete kernel-modules-extra correspondiente. Cuando instalas kernel-modules-extra-6.12.5-200.fc41.x86_64, esos módulos solo funcionan con el kernel 6.12.5-200.fc41. Instala un nuevo kernel y esos módulos son inútiles, necesitas el kernel-modules-extra correspondiente para la nueva versión del kernel.


¿Qué Sucede Durante una Actualización del Sistema?

Durante una actualización mayor de versión de Fedora (por ejemplo, Fedora 43 a 44), dnf system-upgrade descarga e instala paquetes para la nueva versión.

La nueva versión trae un nuevo kernel. Si kernel-modules-extra fue instalado explícitamente (ejecutaste dnf install kernel-modules-extra en algún momento), DNF también debería instalar el paquete correspondiente para el nuevo kernel, pero no siempre.

Si el soporte de xpad fue incluido a través de una cadena de dependencias que cambió entre versiones, o si el paquete fue instalado como una weak dependency, o si hubo un conflicto durante la transacción de actualización, kernel-modules-extra puede desaparecer silenciosamente. El sistema arranca bien porque xpad no es esencial, es solo un driver de gamepad, así que solo lo notarás cuando intentes usar el controller.


Por Qué “udevadm monitor” Es Engañoso

El comando udevadm monitor muestra el dispositivo controller conectándose, pero eso no significa que esté funcionando. La salida solo muestra actividad del bus USB (es decir, el kernel solo detectó que el dispositivo fue conectado).

KERNEL[12345.678] add      /devices/pci0000:00/.../usb1/1-2 (usb)
UDEV  [12345.690] add      /devices/pci0000:00/.../usb1/1-2 (usb)

Lo que realmente quieres verificar es si un driver se vinculó al dispositivo:

# Verificar si xpad reclamó el dispositivo (USB)
lsusb -t | grep xpad

# O verificar en dmesg la vinculación del driver
dmesg | grep -i xpad

Si xpad no está cargado, estos comandos no devuelven nada. El dispositivo es visible en el bus pero está huérfano, sin driver que traduzca sus datos en eventos de entrada.

xbox-controller-flow-linux.webp



La Solución

Para Conexiones USB (xpad)

Verificar si el Module Está Cargado:

  • Si esto no devuelve nada, el module no está cargado.
  • Luego, necesitas cargar el module (si está instalado) o instalarlo.
lsmod | grep xpad

Instalar el Kernel Module Faltante:

  • El module xpad está incluido en el paquete kernel-modules-extra.
  • Instala este paquete si no lo tienes.
sudo dnf install kernel-modules-extra

Cargar el Module y Verificar:

  • Después de instalar, reconecta tu Xbox controller (desconecta y vuelve a conectar el USB) y verifica:
lsmod | grep xpad

# Salida esperada:
# xpad                    32768  0
# ff_memless              20480  1 xpad

Si el Module No se Carga Automáticamente, Cárgalo Manualmente:

# Cargar el module manualmente
sudo modprobe xpad

Hacerlo Persistente Entre Reinicios:

  • Esto le indica a systemd-modules-load.service que cargue xpad al arrancar, sin importar si hay un dispositivo correspondiente conectado.
  • Normalmente udev maneja esto automáticamente (carga el driver correcto cuando se detecta un dispositivo correspondiente), pero hacerlo explícito asegura que siempre esté disponible.
# Asegurar que el module se cargue automáticamente al arrancar
sudo bash -c 'echo "xpad" > /etc/modules-load.d/xpad.conf'

Para Conexiones Bluetooth

Si te conectas vía Bluetooth y el controller se empareja pero no produce entrada, el problema podría ser de hid-generic.

Verificar si el Dispositivo HID fue Creado:

# Buscar dispositivos HID del Xbox controller
ls /dev/input/by-id/ | grep -i xbox

# O verificar en dmesg la vinculación HID
dmesg | grep -i "xbox\|045e"

Para Xbox Series Controllers (firmware 5.x+), Verificar que uhid Esté Disponible:

zgrep UHID /proc/config.gz

# Debería mostrar: CONFIG_UHID=y o CONFIG_UHID=m

Si uhid está compilado como module, asegúrate de que esté cargado:

lsmod | grep uhid

Instalar xpadneo para soporte completo de funciones por Bluetooth:

El driver básico hid-generic te da entrada de botones y sticks por Bluetooth, pero sin rumble, sin reporte de batería, y a veces comportamiento extraño. Para una mejor experiencia, instala el driver xpadneo:

sudo dnf install dkms kernel-devel
git clone https://github.com/atar-axis/xpadneo
cd xpadneo
sudo ./install.sh

Esto instala un module DKMS que se reconstruye automáticamente contra nuevos kernels. Maneja force feedback, estado de batería, trigger rumble, y varias peculiaridades del controller que hid-generic ignora.



Casos de Uso y Drivers

Gaming casual con Steam en Fedora (cable USB): Instala kernel-modules-extra, conecta tu Xbox controller, abre Steam. Eso es todo. El driver xpad maneja todo, Steam Input se encarga del resto. Este es el camino más simple y el más confiable.

Gaming inalámbrico vía Bluetooth: Empareja el controller a través de GNOME Settings o bluetoothctl. La entrada básica funciona a través de hid-generic. Para rumble y reporte de batería, instala xpadneo vía DKMS. Si usas Secure Boot, necesitarás firmar el module DKMS o registrar una Machine Owner Key (MOK).

Gaming de sofá con múltiples controllers: Cada controller conectado obtiene su propio par /dev/input/eventX y /dev/input/jsX. Steam maneja múltiples controllers de forma nativa. La única preocupación es el ancho de banda de Bluetooth si conectas 4 controllers inalámbricamente — un adaptador USB Bluetooth dedicado con soporte BLE ayuda.

Emulación retro (RetroArch, Dolphin, PCSX2): Estos emuladores típicamente usan la gamepad API de SDL2, que lee desde evdev. Si el driver del kernel está funcionando y el dispositivo está en /dev/input/, los emuladores deberían detectarlo automáticamente. RetroArch tiene su propia selección de input driver — asegúrate de que esté configurado para usar udev (no linuxraw) para acceso evdev.



Para Terminar

Este post muestra información más detallada sobre cómo el Xbox controller interactúa con el kernel y pasos para solucionar problemas. Un poco mejor que la versión anterior creo. Espero que le sirva a alguien.