В дополнение к моей предыдущей теме, возникло непонимание, которое пока не сильно устранилось чтением LDD и SO. Требуется реализовать blocking read, по этому есть темы как в LDD так и на SO, сам механизм blocking read не вызвал затруднений.
Я выделил DMA буфер на 256 Кбайт, через MMIO передаю адрес этого буфера и он успешно заполняется, после чего приходит прерывание, в котором можно инициировать чтение следующего блока. Скорость около 170 Мбайт/с (если запросить гигабайт).
Возникла проблема при реализации char device, а именно операции read. Если осуществить copy_to_user в самом этом вызове то всё успешно читается на стороне userspace (cat, dd). Однако в обработчике прерывания copy_to_user не работает, хотя бы потому что он может сам уходить в sleep, что очевидно недопустимо для ISR.
Как же тогда быть? Допустим я запросил прочитать мегабайт из устройства, а буфер 256К - нужно при получении прерывания проснуться и вернуть лишь 256К а пользователь будет затем повторять запросы чтения четыре раза с разным offset (у char-то устройства)? Например dd bs=1M count=1 не повторит.
Нужно выделить буфер в драйвере на мегабайт и затем после его заполнения уже просыпаться и делать copy_to_user всего мегабайта? Получается двойное копирование.