Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0-only */
2#ifndef BLK_MQ_DMA_H
3#define BLK_MQ_DMA_H
4
5#include <linux/blk-mq.h>
6#include <linux/pci-p2pdma.h>
7
8struct blk_map_iter {
9 struct bvec_iter iter;
10 struct bio *bio;
11 struct bio_vec *bvecs;
12 bool is_integrity;
13};
14
15struct blk_dma_iter {
16 /* Output address range for this iteration */
17 dma_addr_t addr;
18 u32 len;
19 struct pci_p2pdma_map_state p2pdma;
20
21 /* Status code. Only valid when blk_rq_dma_map_iter_* returned false */
22 blk_status_t status;
23
24 /* Internal to blk_rq_dma_map_iter_* */
25 struct blk_map_iter iter;
26};
27
28bool blk_rq_dma_map_iter_start(struct request *req, struct device *dma_dev,
29 struct dma_iova_state *state, struct blk_dma_iter *iter);
30bool blk_rq_dma_map_iter_next(struct request *req, struct device *dma_dev,
31 struct blk_dma_iter *iter);
32
33/**
34 * blk_rq_dma_map_coalesce - were all segments coalesced?
35 * @state: DMA state to check
36 *
37 * Returns true if blk_rq_dma_map_iter_start coalesced all segments into a
38 * single DMA range.
39 */
40static inline bool blk_rq_dma_map_coalesce(struct dma_iova_state *state)
41{
42 return dma_use_iova(state);
43}
44
45/**
46 * blk_rq_dma_unmap - try to DMA unmap a request
47 * @req: request to unmap
48 * @dma_dev: device to unmap from
49 * @state: DMA IOVA state
50 * @mapped_len: number of bytes to unmap
51 * @map: peer-to-peer mapping type
52 *
53 * Returns %false if the callers need to manually unmap every DMA segment
54 * mapped using @iter or %true if no work is left to be done.
55 */
56static inline bool blk_rq_dma_unmap(struct request *req, struct device *dma_dev,
57 struct dma_iova_state *state, size_t mapped_len,
58 enum pci_p2pdma_map_type map)
59{
60 if (map == PCI_P2PDMA_MAP_BUS_ADDR)
61 return true;
62
63 if (dma_use_iova(state)) {
64 unsigned int attrs = 0;
65
66 if (map == PCI_P2PDMA_MAP_THRU_HOST_BRIDGE)
67 attrs |= DMA_ATTR_MMIO;
68
69 dma_iova_destroy(dma_dev, state, mapped_len, rq_dma_dir(req),
70 attrs);
71 return true;
72 }
73
74 return !dma_need_unmap(dma_dev);
75}
76#endif /* BLK_MQ_DMA_H */