2008-12-27

Да будет сканер, в Linux

Несколько месяцев назад я занялся порочной практикой - самостоятельной сборкой ядер Linux. Процесс сам по себе не такой уж и сложный, но я, как человек разумный, решил переделать конфигурацию на свой лад, т.е. убрать всё лишнее, всё что не используется на моей домашней (по совместительству рабочей) машине. Тут и начались проблемы, перестало работать то одно устройство, то другое. Приходилось анализировать исходный конфиг (.config, хватило ума не удалять его, как и предыдущее рабочее ядро) со своим.
Вчера потребовался сканер (USB, Epson Perfection 2480 Photo). Боялся что ничего не заработает на моей сборке ядра и, разумеется, так и получилось. Перезагрузил старое ("оригинальное", из коробки Debian Etch, 2.6.18) ядро, всё нормально. Начал искать в чем причина.
$ sane-find-scanner
found USB scanner (vendor=0x04b8, product=0x0121) at libusb:003:002
Т.е. сканер есть, но его нет:
$ scanimage -L
device `v4l:/dev/video0' is a Noname BT878 video (AVerMedia TVPhone virtual device
То же самое, но под root:
$ sudo scanimage -L
Password:
device `v4l:/dev/video0' is a Noname BT878 video (AVerMedia TVPhone virtual device
device `snapscan:libusb:003:002' is a EPSON EPSON Scanner1 flatbed scanner

Вся закавыка заключается в том, что в своей компиляции я убрал устаревшую (DEPRECATED) опцию USB_DEVICE_CLASS. Если посмотреть описание этой опции, а еще ветку libsane udev rules for 2.6.22 в рассылке sane-devel, то становится ясно в чем дело и как поступить. Идем в /etc/udev/rules.d/z60_libsane.rules (в вашей системе, z60_libsane.rules может иметь другой префикс, не z60_). В начале этого файла должны быть строки:
ACTION!="add", GOTO="libsane_rules_end"                                                                                 
ENV{DEVTYPE}=="usb_device", GOTO="libsane_create_usb_dev"
SUBSYSTEM=="usb_device", GOTO="libsane_rules_begin"
SUBSYSTEM!="usb_device", GOTO="libsane_rules_end"

# Kernel >= 2.6.22 jumps here
LABEL="libsane_create_usb_dev"

# For Linux >= 2.6.22 without CONFIG_USB_DEVICE_CLASS=y
# If the following rule does not exist on your system yet, uncomment it
# ENV{DEVTYPE}=="usb_device", NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0664", OWNER="root", GROUP="root"

# Kernel < 2.6.22 jumps here
LABEL="libsane_rules_begin"
Нас интересует строка "If the following rule does not exist on your system yet, uncomment it". Как определить, что такого правила в системе еще нет. Во первых, сканер у нас под обычным пользователем всё еще не работает :-). Во вторых, анализируем выход такой команды:
$ grep -ir 'env{devtype}=="usb_device"' /etc/udev/rules.d/
/etc/udev/rules.d/z60_libsane.rules:ENV{DEVTYPE}=="usb_device", GOTO="libsane_create_usb_dev"
/etc/udev/rules.d/z60_libsane.rules:# ENV{DEVTYPE}=="usb_device", NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0664", OWNER="root", GROUP="root"
/etc/udev/rules.d/z60_libsane-extras.rules:ENV{DEVTYPE}=="usb_device", GOTO="libsane_extras_create_usb_dev"
/etc/udev/rules.d/z60_libsane-extras.rules:# ENV{DEVTYPE}=="usb_device", NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0664", OWNER="root", GROUP="root"
Очевидно, что такого правила нигде больше нет. Снимаем коментарий с известной строки, перезагружаем систему и радуемся, радуемся я сказал :-). У меня всё заработало:
$ scanimage -L
device `v4l:/dev/video0' is a Noname BT878 video (AVerMedia TVPhone virtual device
device `snapscan:libusb:003:002' is a EPSON EPSON Scanner1 flatbed scanner

Комментариев нет: