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