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