понедельник, 26 мая 2008 г.

Безопасное извлечение...

После того, как USB носитель безопасно извлекаеся из Windows, он гаснет, то бишь переходит в отключенное состояние. С одной стороны это минус, чтобы использовать носитель снова, его нужно выткнуть и воткнуть. Но с другой стороны не так уж часто это и нужно, и это правильно.

В то же время все линуксоиды в один голос твердят - размонтировал и спи спокойно.

Практика показывает, что на linux можно сделать все, правда никто не знает как. Разрабатывая по работе проходной шифратор USB наткнулся на проблему безопасного извлечения. Сперва решил ее тривиальным образом - через команду с консоли. Но это не тот уровень, хотелось бы чтобы устройство извлекалось само.

Переписка с разработчиком драйвера USB девайса для pxa270, в попытках выяснить что же шлет windows устройству, не дала никаких результатов. Но отладочная инфрмация g_file_storage дала. Выяснилось, что после безопасного отключения Windows переводит устройство в состояние suspend.

Правда, выяснилось так же, что с пользовательского уровня эта информация недоступна. Не проблема. прикрутил запись в sysfs - стала доступна. После этого я всю голову сломал как заставить std::cin неблокированно возвращать состояние буфера, поскольку паралельно надо еще мониторить файл из /sys, но ничего не придумал отключил консоль полностью. Но Уперся в то, что через Windows то все хорошо отключается, а вот через linux - никак. отмонтировал, но кто сообщит устройству что ему надо отключаться?

Поиск в интернете почти ничего не дал, кроме одного упоминания. Дескать echo suspend > /sys/class/usb_device/usbdev$BUS.$DEVICE/device/power/level заставит устройство уснуть. Было бы хорошо, но 'USB device class-devices' объявлен в ядре как устаревший, эксперементировать с ним не интересно. 'USB selective suspend/resume and wakeup' объявлено как эксперементальное, но нигде толком не написано как им управлять.

Но, методом научного тыка выяснилось, что файл /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-3/power/level обладает аналогичными функциями, и может быть найден через /sys/block/sda/device (симлинк), который указывает на /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-3/1-3:1.0/host8/target8:0:0/8:0:0:0, относительно /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-3 это прямой путь, без симлинков. Иначе я не придумал как можно автоматически определить все эти многочисленные идентификаторы. lsusb такой информации не предоставляет, да и его вывод всеравно надо парсить.

Естественно, все это справедливо только для моей системы, ну кроме разве только sda.

Немного непонятным осталось то, как разбудить устройство снова. echo on > power/level включает питание на устройстве, но монтироваться устройство после этого не желает. Правда где-то я видел файл rescan, послав 1 в который можно заставить его пересканировать USB storage. Ну для меня это не очень актуально, оставляю эту тему для интересующихся.

PS: Правда, где-то в интернете вычитал, что дескать Windows Vista не отключает питание от устройств, это засада.