Создание потоковых отображений DMA
Кстати, возвратные буферы являются одной из причин, почему важно правильно задавать направление. Возвратные буферы при DMA_BIDIRECTIONAL копируются до и после операции, что часто является ненужной тратой циклов процессора. Может возникнуть желание всегда просто указывать DMA_BIDIRECTIONAL, но авторам драйверов не следует поддаваться этому соблазну. На некоторых архитектурах за такой выбор… Читать ещё >
Создание потоковых отображений DMA (реферат, курсовая, диплом, контрольная)
Потоковые отображения по ряду причин имеют более сложный интерфейс, чем согласованный вариант. Эти отображения рассчитывают на работу с буфером, который уже был выделен драйвером, и, следовательно, иметь дело с адресами, которые они не выбирают. На некоторых архитектурах потоковые отображения могут также иметь несколько несоприкасающихся страниц и составные буферы «разборки/сборки». По всем этим причинам потоковые отображения имеют свой собственный набор функций отображения.
При создании потокового отображения вы должны сообщить ядру, в каком направлении движутся данные. Для этой цели были определены некоторые символы (с типом enum dma_data_direction):
DMA_TO_DEVICE.
DMA_FROM_DEVICE.
Эти два символа должна быть достаточно очевидны. Если данные отправляются в устройство (возможно, в ответ на системный вызов write), следует использовать DMA_TO_DEVICE; данные, идущие в процессор, наоборот, обозначаются DMA_FROM_DEVICE.
DMA_BIDIRECTIONAL.
Если данные могут двигаться в любом направлении, используйте DMA_BIDIRECTIONAL.
DMA_NONE.
Этот символ предоставляется только как помощь при отладке. Попытки использовать буферы с этим «направлением» вызовут панику ядра.
Может возникнуть желание всегда просто указывать DMA_BIDIRECTIONAL, но авторам драйверов не следует поддаваться этому соблазну. На некоторых архитектурах за такой выбор придётся заплатить падением производительности.
Если у вас для передачи есть единственный буфер, отображайте его с помощью dma_map_single:
dma_addr_t dma_map_single (struct device *dev, void *buffer, size_t size,.
enum dma_data_direction direction);
Возвращаемым значением является шинный адрес, который вы можете передать в устройство или NULL, если что-то пойдёт не так.
После завершения передачи отображение должно быть удалено с помощью dma_unmap_single:
void dma_unmap_single (struct device *dev, dma_addr_t dma_addr, size_t size,.
enum dma_data_direction direction);
Здесь, аргументы size и direction должны соответствовать тем, которые использовались для отображения буфера.
Для потокового отображения DMA применяются некоторые важные правила:
- *Буфер должен быть использован только для передачи, которая соответствует значению заданного при отображении направления.
- *После того, как буфер был отображён, он принадлежит устройству, а не процессору. До тех пор, пока буфер не отключён, драйвер не должен касаться его содержимого любым способом. Драйверу безопасно обращаться к содержимому буфера только после того, как была вызвана dma_unmap_single (с одним исключением, которое мы увидим в ближайшее время). Среди прочего, это правило предполагает, что буфер записи для устройство не может быть отображён, пока он не содержит все данные для записи.
- *Буфер не должен быть отключён во время активности DMA, либо гарантирована серьёзная нестабильность системы.
Вы можете быть удивлены, почему драйвер не может работать с буфером, как только он был отображён. Фактически, есть две причины, почему это правило имеет смысл. Во-первых, когда буфер отображается для DMA, ядро должно гарантировать, что все данные в этом буфере были записаны в память на самом деле. Вполне вероятно, что когда вызывается dma_map_single, некоторые данные находятся в кэше процессора и должны быть явно сброшены в память. Данные, записанные в буфер процессором после сброса, могут быть не видны для устройства.
Во-вторых, рассмотрим, что произойдёт, если буфер отображён в область памяти, которая не доступна для устройства. Некоторые архитектуры в этом случае просто дают ошибку, но другие создают возвратный буфер. Возвратный буфер — это просто отдельная область памяти, доступная для устройства. Если буфер отображается с направлением DMA_TO_DEVICE и требуется возвратный буфер, содержимое оригинального буфера копируется как часть операции отображения. Ясно, что изменения в оригинальном буфере после копирования устройству не видны. Аналогичным образом при DMA_FROM_DEVICE возвратные буферы копируются обратно в исходный буфер функцией dma_unmap_single; данные из устройства не имеют смысла, пока не выполнено это копирование.
Кстати, возвратные буферы являются одной из причин, почему важно правильно задавать направление. Возвратные буферы при DMA_BIDIRECTIONAL копируются до и после операции, что часто является ненужной тратой циклов процессора.
Иногда драйверу необходимо получить доступ к содержимому потокового буфера DMA без его отключения. Это делает возможным следующий вызов:
void dma_sync_single_for_cpu (struct device *dev, dma_handle_t bus_addr, size_t size, enum dma_data_direction direction);
Эта функция должна быть вызвана перед тем, как процессор обращается к потоковому буферу DMA. После того, как вызов был сделан, процессор «владеет» буфером DMA и может работать с ним, как это требуется. Однако, перед доступом в буфер устройства, право собственности должно быть ему возвращено:
void dma_sync_single_for_device (struct device *dev, dma_handle_t bus_addr,.
size_t size, enum dma_data_direction direction);
Процессор, опять же, не должен обращаться к буферу DMA после того, как был сделан этот вызов.