xref: /haiku/src/system/kernel/device_manager/dma_resources.h (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
4  * Distributed under the terms of the MIT License.
5  */
6 #ifndef DMA_RESOURCES_H
7 #define DMA_RESOURCES_H
8 
9 #include <sys/uio.h>
10 
11 #include <lock.h>
12 #include <util/DoublyLinkedList.h>
13 
14 
15 struct device_node;
16 struct IOOperation;
17 struct IORequest;
18 
19 
20 struct dma_restrictions {
21 	addr_t	low_address;
22 	addr_t	high_address;
23 	size_t	alignment;
24 	size_t	boundary;
25 	size_t	max_transfer_size;
26 	uint32	max_segment_count;
27 	size_t	max_segment_size;
28 	uint32	flags;
29 };
30 
31 
32 struct DMABounceBuffer : public DoublyLinkedListLinkImpl<DMABounceBuffer> {
33 	void*	address;
34 	addr_t	physical_address;
35 	size_t	size;
36 };
37 
38 typedef DoublyLinkedList<DMABounceBuffer> DMABounceBufferList;
39 
40 
41 class DMABuffer : public DoublyLinkedListLinkImpl<DMABuffer> {
42 public:
43 	static	DMABuffer*			Create(size_t count);
44 
45 			iovec*				Vecs() { return fVecs; }
46 			iovec&				VecAt(size_t index) { return fVecs[index]; }
47 			uint32				VecCount() const { return fVecCount; }
48 			void				SetVecCount(uint32 count);
49 
50 			void				AddVec(void* base, size_t size);
51 
52 			void				SetBounceBuffer(DMABounceBuffer* bounceBuffer)
53 									{ fBounceBuffer = bounceBuffer; }
54 			DMABounceBuffer*	BounceBuffer() const { return fBounceBuffer; }
55 
56 			void*				BounceBufferAddress() const
57 									{ return fBounceBuffer
58 										? fBounceBuffer->address : NULL; }
59 			addr_t				PhysicalBounceBufferAddress() const
60 									{ return fBounceBuffer
61 										? fBounceBuffer->physical_address
62 										: 0; }
63 			size_t				BounceBufferSize() const
64 									{ return fBounceBuffer
65 										? fBounceBuffer->size : 0; }
66 
67 			bool				UsesBounceBufferAt(uint32 index);
68 
69 			void				Dump() const;
70 
71 private:
72 			DMABounceBuffer*	fBounceBuffer;
73 			uint32				fVecCount;
74 			iovec				fVecs[1];
75 };
76 
77 
78 typedef DoublyLinkedList<DMABuffer> DMABufferList;
79 
80 
81 class DMAResource {
82 public:
83 								DMAResource();
84 								~DMAResource();
85 
86 			status_t			Init(const dma_restrictions& restrictions,
87 									size_t blockSize, uint32 bufferCount,
88 									uint32 bounceBufferCount);
89 			status_t			Init(device_node* node, size_t blockSize,
90 									uint32 bufferCount,
91 									uint32 bounceBufferCount);
92 
93 			status_t			CreateBuffer(DMABuffer** _buffer);
94 			status_t			CreateBounceBuffer(DMABounceBuffer** _buffer);
95 
96 			status_t			TranslateNext(IORequest* request,
97 									IOOperation* operation,
98 									size_t maxOperationLength);
99 			void				RecycleBuffer(DMABuffer* buffer);
100 
101 			size_t				BlockSize() const	{ return fBlockSize; }
102 			uint32				BufferCount() const { return fBufferCount; }
103 
104 private:
105 			bool				_NeedsBoundsBuffers() const;
106 			void				_RestrictBoundaryAndSegmentSize(addr_t base,
107 									addr_t& length);
108 			void				_CutBuffer(DMABuffer& buffer,
109 									addr_t& physicalBounceBuffer,
110 									size_t& bounceLeft, size_t toCut);
111 			size_t				_AddBounceBuffer(DMABuffer& buffer,
112 									addr_t& physicalBounceBuffer,
113 									size_t& bounceLeft, size_t length,
114 									bool fixedLength);
115 
116 			mutex				fLock;
117 			dma_restrictions	fRestrictions;
118 			size_t				fBlockSize;
119 			uint32				fBufferCount;
120 			uint32				fBounceBufferCount;
121 			size_t				fBounceBufferSize;
122 			DMABufferList		fDMABuffers;
123 			DMABounceBufferList	fBounceBuffers;
124 			iovec*				fScratchVecs;
125 };
126 
127 #endif	// DMA_RESOURCES_H
128