1 |
/* |
---|
2 |
* Copyright (C) 2005-2007 by Daniel Wagner |
---|
3 |
* Copyright (C) 2005-2007 by Pieter Palmers |
---|
4 |
* |
---|
5 |
* This file is part of FFADO |
---|
6 |
* FFADO = Free Firewire (pro-)audio drivers for linux |
---|
7 |
* |
---|
8 |
* FFADO is based upon FreeBoB |
---|
9 |
* |
---|
10 |
* This library is free software; you can redistribute it and/or |
---|
11 |
* modify it under the terms of the GNU Lesser General Public |
---|
12 |
* License version 2.1, as published by the Free Software Foundation; |
---|
13 |
* |
---|
14 |
* This library is distributed in the hope that it will be useful, |
---|
15 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
16 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
17 |
* Lesser General Public License for more details. |
---|
18 |
* |
---|
19 |
* You should have received a copy of the GNU Lesser General Public |
---|
20 |
* License along with this library; if not, write to the Free Software |
---|
21 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
---|
22 |
* MA 02110-1301 USA |
---|
23 |
*/ |
---|
24 |
|
---|
25 |
#ifndef FFADO_IEEE1394SERVICE_H |
---|
26 |
#define FFADO_IEEE1394SERVICE_H |
---|
27 |
|
---|
28 |
#include "fbtypes.h" |
---|
29 |
#include "threads.h" |
---|
30 |
|
---|
31 |
#include "debugmodule/debugmodule.h" |
---|
32 |
|
---|
33 |
#include "IEC61883.h" |
---|
34 |
|
---|
35 |
#include <libraw1394/raw1394.h> |
---|
36 |
#include <pthread.h> |
---|
37 |
|
---|
38 |
#include <vector> |
---|
39 |
#include <string> |
---|
40 |
|
---|
41 |
class ARMHandler; |
---|
42 |
|
---|
43 |
class Ieee1394Service : public IEC61883 { |
---|
44 |
public: |
---|
45 |
Ieee1394Service(); |
---|
46 |
~Ieee1394Service(); |
---|
47 |
|
---|
48 |
bool initialize( int port ); |
---|
49 |
|
---|
50 |
/** |
---|
51 |
* @brief get number of ports (firewire adapters) in this machine |
---|
52 |
* |
---|
53 |
* @return the number of ports |
---|
54 |
*/ |
---|
55 |
static unsigned int detectNbPorts(); |
---|
56 |
|
---|
57 |
/** |
---|
58 |
* @brief get port (adapter) id |
---|
59 |
* |
---|
60 |
* @return get port (adapter) id |
---|
61 |
*/ |
---|
62 |
int getPort() |
---|
63 |
{ return m_port; } |
---|
64 |
|
---|
65 |
/** |
---|
66 |
* @brief get port (adapter) name |
---|
67 |
* |
---|
68 |
* @return get port (adapter) name |
---|
69 |
*/ |
---|
70 |
std::string getPortName() |
---|
71 |
{ return m_portName; }; |
---|
72 |
|
---|
73 |
/** |
---|
74 |
* @brief get number of nodes on the bus |
---|
75 |
* |
---|
76 |
* Since the root node always has |
---|
77 |
* the highest node ID, this number can be used to determine that ID (it's |
---|
78 |
* LOCAL_BUS|(count-1)). |
---|
79 |
* |
---|
80 |
* @return the number of nodes on the bus to which the port is connected. |
---|
81 |
* This value can change with every bus reset. |
---|
82 |
*/ |
---|
83 |
int getNodeCount(); |
---|
84 |
|
---|
85 |
/** |
---|
86 |
* @brief get the node id of the local node |
---|
87 |
* |
---|
88 |
* @note does not include the bus part (0xFFC0) |
---|
89 |
* |
---|
90 |
* @return the node id of the local node |
---|
91 |
* This value can change with every bus reset. |
---|
92 |
*/ |
---|
93 |
nodeid_t getLocalNodeId(); |
---|
94 |
|
---|
95 |
/** |
---|
96 |
* @brief send async read request to a node and wait for response. |
---|
97 |
* |
---|
98 |
* This does the complete transaction and will return when it's finished. |
---|
99 |
* |
---|
100 |
* @param node target node (\todo needs 0xffc0 stuff) |
---|
101 |
* @param addr address to read from |
---|
102 |
* @param length amount of data to read in quadlets |
---|
103 |
* @param buffer pointer to buffer where data will be saved |
---|
104 |
|
---|
105 |
* @return true on success or false on failure (sets errno) |
---|
106 |
*/ |
---|
107 |
bool read( fb_nodeid_t nodeId, |
---|
108 |
fb_nodeaddr_t addr, |
---|
109 |
size_t length, |
---|
110 |
fb_quadlet_t* buffer ); |
---|
111 |
|
---|
112 |
bool read_quadlet( fb_nodeid_t nodeId, |
---|
113 |
fb_nodeaddr_t addr, |
---|
114 |
fb_quadlet_t* buffer ); |
---|
115 |
|
---|
116 |
bool read_octlet( fb_nodeid_t nodeId, |
---|
117 |
fb_nodeaddr_t addr, |
---|
118 |
fb_octlet_t* buffer ); |
---|
119 |
|
---|
120 |
/** |
---|
121 |
* @brief send async write request to a node and wait for response. |
---|
122 |
* |
---|
123 |
* This does the complete transaction and will return when it's finished. |
---|
124 |
* |
---|
125 |
* @param node target node (\XXX needs 0xffc0 stuff) |
---|
126 |
* @param addr address to write to |
---|
127 |
* @param length amount of data to write in quadlets |
---|
128 |
* @param data pointer to data to be sent |
---|
129 |
* |
---|
130 |
* @return true on success or false on failure (sets errno) |
---|
131 |
*/ |
---|
132 |
bool write( fb_nodeid_t nodeId, |
---|
133 |
fb_nodeaddr_t addr, |
---|
134 |
size_t length, |
---|
135 |
fb_quadlet_t* data ); |
---|
136 |
|
---|
137 |
bool write_quadlet( fb_nodeid_t nodeId, |
---|
138 |
fb_nodeaddr_t addr, |
---|
139 |
fb_quadlet_t data ); |
---|
140 |
|
---|
141 |
bool write_octlet( fb_nodeid_t nodeId, |
---|
142 |
fb_nodeaddr_t addr, |
---|
143 |
fb_octlet_t data ); |
---|
144 |
|
---|
145 |
/** |
---|
146 |
* @brief send 64-bit compare-swap lock request and wait for response. |
---|
147 |
* |
---|
148 |
* swaps the content of \ref addr with \ref swap_value , but only if |
---|
149 |
* the content of \ref addr equals \ref compare_with |
---|
150 |
* |
---|
151 |
* @note takes care of endiannes |
---|
152 |
* |
---|
153 |
* @param nodeId target node ID |
---|
154 |
* @param addr address within target node address space |
---|
155 |
* @param compare_with value to compare \ref addr with |
---|
156 |
* @param swap_value new value to put in \ref addr |
---|
157 |
* @param result the value (originally) in \ref addr |
---|
158 |
* |
---|
159 |
* @return true if succesful, false otherwise |
---|
160 |
*/ |
---|
161 |
bool lockCompareSwap64( fb_nodeid_t nodeId, |
---|
162 |
fb_nodeaddr_t addr, |
---|
163 |
fb_octlet_t compare_value, |
---|
164 |
fb_octlet_t swap_value, |
---|
165 |
fb_octlet_t* result ); |
---|
166 |
|
---|
167 |
fb_quadlet_t* transactionBlock( fb_nodeid_t nodeId, |
---|
168 |
fb_quadlet_t* buf, |
---|
169 |
int len, |
---|
170 |
unsigned int* resp_len ); |
---|
171 |
|
---|
172 |
bool transactionBlockClose(); |
---|
173 |
|
---|
174 |
raw1394handle_t getHandle() {return m_handle;}; |
---|
175 |
|
---|
176 |
int getVerboseLevel(); |
---|
177 |
|
---|
178 |
bool addBusResetHandler( Functor* functor ); |
---|
179 |
bool remBusResetHandler( Functor* functor ); |
---|
180 |
|
---|
181 |
/** |
---|
182 |
* @brief get the current generation |
---|
183 |
* |
---|
184 |
* @return the current generation |
---|
185 |
**/ |
---|
186 |
unsigned int getGeneration() { |
---|
187 |
return raw1394_get_generation( m_handle ); |
---|
188 |
} |
---|
189 |
|
---|
190 |
/** |
---|
191 |
* @brief register an AddressRangeMapping Handler |
---|
192 |
* @param h pointer to the handler to register |
---|
193 |
* |
---|
194 |
* @return true on success or false on failure |
---|
195 |
**/ |
---|
196 |
|
---|
197 |
bool registerARMHandler( ARMHandler *h ); |
---|
198 |
|
---|
199 |
/** |
---|
200 |
* @brief unregister ARM range |
---|
201 |
* @param h pointer to the handler to unregister |
---|
202 |
* @return true if successful, false otherwise |
---|
203 |
*/ |
---|
204 |
bool unregisterARMHandler( ARMHandler *h ); |
---|
205 |
|
---|
206 |
nodeaddr_t findFreeARMBlock( nodeaddr_t start, size_t length, size_t step ); |
---|
207 |
|
---|
208 |
// ISO channel stuff |
---|
209 |
public: |
---|
210 |
signed int getAvailableBandwidth(); |
---|
211 |
signed int allocateIsoChannelGeneric(unsigned int bandwidth); |
---|
212 |
signed int allocateIsoChannelCMP(nodeid_t xmit_node, int xmit_plug, |
---|
213 |
nodeid_t recv_node, int recv_plug); |
---|
214 |
bool freeIsoChannel(signed int channel); |
---|
215 |
|
---|
216 |
private: |
---|
217 |
enum EAllocType { |
---|
218 |
AllocFree = 0, // not allocated (by us) |
---|
219 |
AllocGeneric = 1, // allocated with generic functions |
---|
220 |
AllocCMP=2 // allocated with CMP |
---|
221 |
}; |
---|
222 |
|
---|
223 |
struct ChannelInfo { |
---|
224 |
int channel; |
---|
225 |
int bandwidth; |
---|
226 |
enum EAllocType alloctype; |
---|
227 |
nodeid_t xmit_node; |
---|
228 |
int xmit_plug; |
---|
229 |
nodeid_t recv_node; |
---|
230 |
int recv_plug; |
---|
231 |
}; |
---|
232 |
|
---|
233 |
// the info for the channels we manage |
---|
234 |
struct ChannelInfo m_channels[64]; |
---|
235 |
|
---|
236 |
bool unregisterIsoChannel(unsigned int c); |
---|
237 |
bool registerIsoChannel(unsigned int c, struct ChannelInfo cinfo); |
---|
238 |
|
---|
239 |
private: |
---|
240 |
|
---|
241 |
bool startRHThread(); |
---|
242 |
void stopRHThread(); |
---|
243 |
static void* rHThread( void* arg ); |
---|
244 |
|
---|
245 |
void printBuffer( unsigned int level, size_t length, fb_quadlet_t* buffer ) const; |
---|
246 |
void printBufferBytes( unsigned int level, size_t length, byte_t* buffer ) const; |
---|
247 |
|
---|
248 |
static int resetHandlerLowLevel( raw1394handle_t handle, |
---|
249 |
unsigned int generation ); |
---|
250 |
bool resetHandler( unsigned int generation ); |
---|
251 |
|
---|
252 |
static int armHandlerLowLevel(raw1394handle_t handle, unsigned long arm_tag, |
---|
253 |
byte_t request_type, unsigned int requested_length, |
---|
254 |
void *data); |
---|
255 |
bool armHandler( unsigned long arm_tag, |
---|
256 |
byte_t request_type, unsigned int requested_length, |
---|
257 |
void *data); |
---|
258 |
|
---|
259 |
raw1394handle_t m_handle; |
---|
260 |
raw1394handle_t m_resetHandle; |
---|
261 |
int m_port; |
---|
262 |
std::string m_portName; |
---|
263 |
|
---|
264 |
pthread_t m_thread; |
---|
265 |
pthread_mutex_t m_mutex; |
---|
266 |
bool m_threadRunning; |
---|
267 |
|
---|
268 |
typedef std::vector< Functor* > reset_handler_vec_t; |
---|
269 |
reset_handler_vec_t m_busResetHandlers; |
---|
270 |
|
---|
271 |
// ARM stuff |
---|
272 |
arm_tag_handler_t m_default_arm_handler; |
---|
273 |
|
---|
274 |
typedef std::vector< ARMHandler * > arm_handler_vec_t; |
---|
275 |
arm_handler_vec_t m_armHandlers; |
---|
276 |
|
---|
277 |
fb_octlet_t byteSwap_octlet(fb_octlet_t value); |
---|
278 |
|
---|
279 |
public: |
---|
280 |
void setVerboseLevel(int l); |
---|
281 |
void show(); |
---|
282 |
private: |
---|
283 |
DECLARE_DEBUG_MODULE; |
---|
284 |
}; |
---|
285 |
|
---|
286 |
#endif // FFADO_IEEE1394SERVICE_H |
---|