dma_resources.h revision 8faff60c7fe72c4dc62b3e823faac1fe244e43d5
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
15struct IOOperation;
16struct IORequest;
17
18
19struct dma_restrictions {
20	addr_t	low_address;
21	addr_t	high_address;
22	size_t	alignment;
23	size_t	boundary;
24	size_t	max_transfer_size;
25	uint32	max_segment_count;
26	size_t	max_segment_size;
27	uint32	flags;
28};
29
30
31class DMABuffer : public DoublyLinkedListLinkImpl<DMABuffer> {
32public:
33	static	DMABuffer*			Create(size_t count, void* bounceBuffer,
34									addr_t physicalBounceBuffer,
35									size_t bounceBufferSize);
36
37			iovec*				Vecs() { return fVecs; }
38			iovec&				VecAt(size_t index) { return fVecs[index]; }
39			uint32				VecCount() const { return fVecCount; }
40			void				SetVecCount(uint32 count);
41
42			void				AddVec(void* base, size_t size);
43
44			void*				BounceBuffer() const { return fBounceBuffer; }
45			addr_t				PhysicalBounceBuffer() const
46									{ return fPhysicalBounceBuffer; }
47			size_t				BounceBufferSize() const
48									{ return fBounceBufferSize; }
49
50			bool				UsesBounceBufferAt(uint32 index);
51			void				SetToBounceBuffer(size_t length);
52
53private:
54			void*				fBounceBuffer;
55			addr_t				fPhysicalBounceBuffer;
56			size_t				fBounceBufferSize;
57			uint32				fVecCount;
58			iovec				fVecs[1];
59};
60
61
62typedef DoublyLinkedList<DMABuffer> DMABufferList;
63
64
65class DMAResource {
66public:
67								DMAResource();
68								~DMAResource();
69
70			status_t			Init(const dma_restrictions& restrictions,
71									size_t blockSize, uint32 bufferCount);
72
73			status_t			CreateBuffer(DMABuffer** _buffer)
74									{ return CreateBuffer(0, _buffer); }
75			status_t			CreateBuffer(size_t size, DMABuffer** _buffer);
76
77			status_t			TranslateNext(IORequest* request,
78									IOOperation* operation);
79			void				RecycleBuffer(DMABuffer* buffer);
80
81			uint32				BufferCount() const { return fBufferCount; }
82
83private:
84			bool				_NeedsBoundsBuffers() const;
85			void				_RestrictBoundaryAndSegmentSize(addr_t base,
86									addr_t& length);
87			void				_CutBuffer(DMABuffer& buffer,
88									addr_t& physicalBounceBuffer,
89									size_t& bounceLeft, size_t toCut);
90			size_t				_AddBounceBuffer(DMABuffer& buffer,
91									addr_t& physicalBounceBuffer,
92									size_t& bounceLeft, size_t length,
93									bool fixedLength);
94
95			mutex				fLock;
96			dma_restrictions	fRestrictions;
97			size_t				fBlockSize;
98			uint32				fBufferCount;
99			size_t				fBounceBufferSize;
100			DMABufferList		fDMABuffers;
101			iovec*				fScratchVecs;
102};
103
104#endif	// DMA_RESOURCES_H
105