Базовое обобщенное блочное устройство имеет open, close (освобождение), ioctl и, что самое главное, функцию request. По крайней мере функции open и close могут быть простыми счетчиками. Интерфейс ioctl() может использоваться для отладки и выполнения измерений при прохождении через различные слои программного обеспечения. Функция request, вызываемая, когда запрос помещается в очередь файловой системой, извлекает структуру запроса и обрабатывает его содержимое. В зависимости от того, является ли запрос запросом на чтение или на запись, устройство выполняет соответствующее действие.
К очереди запросов нельзя получить прямой доступ, а только через вспомогательные функции. (Их можно найти в driver/block/elevator.с и include/linux/ blkdev.h.) Для сохранения совместимости с базовой моделью устройства мы можем включить возможность взаимодействия со следующим запросом в нашу функцию request:
drivers/block/elevator.с
186 struct request *elv_next_request (request_queue_t *q)
Эта вспомогательная функция возвращает указатель на следующую структуру запроса. Проверяя ее элементы, драйвер может получить всю информацию, необходимую для определения размера, направления и других дополнительных операций, связанных с данной очередью.
Когда драйвер завершает запрос, он сообщает об этом ядру с помощью вспомогательной функции end_request ():
drivers/block/ll_rw_blk.с
2599 void end_request(struct request *req, int uptodate)
2600 {
2601 if (!end_that_request_first(req, uptodate,req->hard_cur_sectors)) {
2602 add_disk_randomness(req->rq_disk);
2603 blkdev_dequeue_request(req);
2604 end_that_request_last(req);
2605 }
2606 }
elev_next_request (). Строка 2601
end_that_request_f irst () передает соответствующее количество секторов [если секторы находятся близко, просто возвращается end_request ()].
Строка 2602
Добавляет в систему пул энтропии. Пул энтропии - это способ генерации случайных номеров в системе из функции, достаточно быстрой для вызова во время обработки прерываний. Базовая идея заключается в том, чтобы собрать байты из данных разных драйверов в системе и сгенерировать на их основе случайное число. Это обсуждается в гл. 10, «Добавление вашего кода в ядро». Еще одно объяснение находится в конце /drivers/char/random, с.
Строка 2603
Удаление структуры запроса из очереди.
Строка 2604
Сбор статистики и приготовление структуры к освобождению.
В этой точке обобщенный драйвер обслуживает запросы до их освобождения.
В соответствии с рис. 5.4 мы имеем слой обобщенного блочного устройства, создающего и поддерживающего очереди запросов. Последним слоем в системе блочного ввода-вывода является аппаратный (или специальный) драйвер устройства. Аппаратный драйвер устройства использует вспомогательные функции очереди запросов из обобщенного слоя для обслуживания запросов из зарегистрированной очереди запросов и передает уведомление, когда запрос завершен.
Аппаратный драйвер устройства обладает знаниями о нижестоящем оборудовании относительно их регистров, ввода-вывода, таймера, прерываний и DMA (обсуждается в подразд. 5.2.9, «Прямой доступ к памяти (DMA)»). (Подробности реализации драйверов для ШЕ и SCSI лежат за пределами рассмотрения этой главы. Мы рассмотрим подробнее аппаратные драйверы устройств в гл. 10, а серия проектов поможет вам написать каркас для собственного драйвера.)