root/branches/libffado-2.0/src/libieee1394/ieee1394service.h

Revision 1409, 13.0 kB (checked in by ppalmers, 15 years ago)

small addition

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Copyright (C) 2005-2008 by Daniel Wagner
3  * Copyright (C) 2005-2008 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 program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #ifndef FFADO_IEEE1394SERVICE_H
26 #define FFADO_IEEE1394SERVICE_H
27
28 #include "fbtypes.h"
29 #include "libutil/Functors.h"
30 #include "libutil/Mutex.h"
31
32 #include "debugmodule/debugmodule.h"
33
34 #include "IEC61883.h"
35
36 #include <libraw1394/raw1394.h>
37 #include <pthread.h>
38
39 #include <vector>
40 #include <string>
41
42 #define MAX_FCP_BLOCK_SIZE_BYTES (512)
43 #define MAX_FCP_BLOCK_SIZE_QUADS (MAX_FCP_BLOCK_SIZE_BYTES / 4)
44
45 class IsoHandlerManager;
46 class CycleTimerHelper;
47
48 namespace Util {
49     class Watchdog;
50     class Configuration;
51 }
52
53 class Ieee1394Service : public IEC61883 {
54 public:
55     Ieee1394Service();
56     Ieee1394Service(bool rt, int prio);
57     ~Ieee1394Service();
58
59     bool initialize( int port );
60     bool setThreadParameters(bool rt, int priority);
61     Util::Watchdog *getWatchdog() {return m_pWatchdog;};
62
63    /**
64     * @brief get number of ports (firewire adapters) in this machine
65     *
66     * @return the number of ports
67     */
68     static int detectNbPorts();
69
70    /**
71     * @brief get port (adapter) id
72     *
73     * @return get port (adapter) id
74     */
75     int getPort()
76         { return m_port; }
77
78    /**
79     * @brief get port (adapter) name
80     *
81     * @return get port (adapter) name
82     */
83     std::string getPortName()
84         { return m_portName; };
85
86    /**
87     * @brief get number of nodes on the bus
88     *
89     * Since the root node always has
90     * the highest node ID, this number can be used to determine that ID (it's
91     * LOCAL_BUS|(count-1)).
92     *
93     * @return the number of nodes on the bus to which the port is connected.
94     * This value can change with every bus reset.
95     */
96     int getNodeCount();
97
98    /**
99     * @brief get the node id of the local node
100     *
101     * @note does not include the bus part (0xFFC0)
102     *
103     * @return the node id of the local node
104     * This value can change with every bus reset.
105     */
106     nodeid_t getLocalNodeId();
107
108     /**
109      * @brief get the most recent cycle timer value (in ticks)
110      *
111      * @note Uses the most appropriate method for getting the cycle timer
112      *       which is not necessarily a direct read (could be DLL)
113      */
114     uint32_t getCycleTimerTicks();
115
116     /**
117      * @brief get the most recent cycle timer value (in CTR format)
118      *
119      * @note Uses the most appropriate method for getting the cycle timer
120      *       which is not necessarily a direct read (could be DLL)
121      */
122     uint32_t getCycleTimer();
123
124     /**
125      * @brief get the cycle timer value for a specific time instant (in ticks)
126      *
127      * @note Uses the most appropriate method for getting the cycle timer
128      *       which is not necessarily a direct read (could be DLL)
129      */
130     uint32_t getCycleTimerTicks(uint64_t t);
131
132     /**
133      * @brief get the cycle timer value for a specific time instant (in CTR format)
134      *
135      * @note Uses the most appropriate method for getting the cycle timer
136      *       which is not necessarily a direct read (could be DLL)
137      */
138     uint32_t getCycleTimer(uint64_t t);
139
140     /**
141      * @brief get the system time for a specific cycle timer value (in ticks)
142      * @note thread safe
143      */
144     uint64_t getSystemTimeForCycleTimerTicks(uint32_t ticks);
145
146     /**
147      * @brief get the system time for a specific cycle timer value (in CTR format)
148      * @note thread safe
149      */
150     uint64_t getSystemTimeForCycleTimer(uint32_t ctr);
151
152     /**
153      * @brief read the cycle timer value from the controller (in CTR format)
154      *
155      * @note Uses a direct method to read the value from the controller
156      * @return true if successful
157      */
158     bool readCycleTimerReg(uint32_t *cycle_timer, uint64_t *local_time);
159
160     /**
161      * @brief provide the current system time
162      * @return
163      */
164     uint64_t getCurrentTimeAsUsecs();
165
166     /**
167      * @brief send async read request to a node and wait for response.
168      *
169      * This does the complete transaction and will return when it's finished.
170      *
171      * @param node target node (\todo needs 0xffc0 stuff)
172      * @param addr address to read from
173      * @param length amount of data to read in quadlets
174      * @param buffer pointer to buffer where data will be saved
175      *
176      * @return true on success or false on failure (sets errno)
177      */
178     bool read( fb_nodeid_t nodeId,
179            fb_nodeaddr_t addr,
180            size_t length,
181            fb_quadlet_t* buffer );
182
183     bool read_quadlet( fb_nodeid_t nodeId,
184                        fb_nodeaddr_t addr,
185                        fb_quadlet_t* buffer );
186
187     bool read_octlet( fb_nodeid_t nodeId,
188                       fb_nodeaddr_t addr,
189                       fb_octlet_t* buffer );
190
191     /**
192     * @brief send async write request to a node and wait for response.
193     *
194     * This does the complete transaction and will return when it's finished.
195     *
196     * @param node target node (\XXX needs 0xffc0 stuff)
197     * @param addr address to write to
198     * @param length amount of data to write in quadlets
199     * @param data pointer to data to be sent
200     *
201     * @return true on success or false on failure (sets errno)
202     */
203     bool write( fb_nodeid_t nodeId,
204         fb_nodeaddr_t addr,
205         size_t length,
206         fb_quadlet_t* data );
207
208     bool write_quadlet( fb_nodeid_t nodeId,
209                         fb_nodeaddr_t addr,
210                         fb_quadlet_t data );
211
212     bool write_octlet(  fb_nodeid_t nodeId,
213                         fb_nodeaddr_t addr,
214                         fb_octlet_t data );
215
216     /**
217      * @brief send 64-bit compare-swap lock request and wait for response.
218      *
219      * swaps the content of \ref addr with \ref swap_value , but only if
220      * the content of \ref addr equals \ref compare_with
221      *
222      * @note takes care of endiannes
223      *
224      * @param nodeId target node ID
225      * @param addr address within target node address space
226      * @param compare_with value to compare \ref addr with
227      * @param swap_value new value to put in \ref addr
228      * @param result the value (originally) in \ref addr
229      *
230      * @return true if succesful, false otherwise
231      */
232     bool lockCompareSwap64( fb_nodeid_t nodeId,
233                             fb_nodeaddr_t addr,
234                             fb_octlet_t  compare_value,
235                             fb_octlet_t  swap_value,
236                             fb_octlet_t* result );
237
238     /**
239      * initiate AV/C transaction
240      * @param nodeId
241      * @param buf
242      * @param len
243      * @param resp_len
244      * @return
245      */
246     fb_quadlet_t* transactionBlock( fb_nodeid_t nodeId,
247                                     fb_quadlet_t* buf,
248                                     int len,
249                                     unsigned int* resp_len );
250
251     /**
252      * close AV/C transaction.
253      * @param nodeId
254      * @param buf
255      * @param len
256      * @param resp_len
257      * @return
258      */
259     bool transactionBlockClose();
260
261     int getVerboseLevel();
262
263     bool addBusResetHandler( Util::Functor* functor );
264     bool remBusResetHandler( Util::Functor* functor );
265
266     void doBusReset();
267     bool waitForBusResetStormToEnd( int nb_tries, int sleep_time_ms );
268
269     /**
270      * @brief get the current generation
271      *
272      * @return the current generation
273      **/
274     unsigned int getGeneration() {
275         Util::MutexLockHelper lock(*m_handle_lock);
276         return raw1394_get_generation( m_handle );
277     }
278
279     /**
280      * @brief update the current generation
281      *
282      * @return the current generation
283      **/
284     void updateGeneration() {
285         Util::MutexLockHelper lock(*m_handle_lock);
286         raw1394_update_generation( m_handle, getGeneration());
287     }
288
289     /**
290      * @brief sets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers
291      *
292      * sets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers on node
293      * nodeId such that the timeout is equal to timeout
294      *
295      * @param nodeId node to set CSR registers on
296      * @param timeout timeout in usecs
297      * @return true if successful
298      */
299     bool setSplitTimeoutUsecs(fb_nodeid_t nodeId, unsigned int timeout);
300
301     /**
302      * @brief gets the SPLIT_TIMEOUT_X timeout value
303      *
304      * gets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers on node
305      * nodeId and recombine them into one usec value
306      *
307      * @param nodeId node to get CSR registers from
308      * @return timeout in usecs if successful, 0 else
309      */
310     int getSplitTimeoutUsecs(fb_nodeid_t nodeId);
311
312     /**
313      * @brief use the provided configuration for this service
314      *
315      * only update the config once, before init. not thread safe,
316      * and no effect when things are already running.
317      *
318      * @param c configuration to use
319      * @return bool if this config is ok.
320      */
321     bool useConfiguration(Util::Configuration *c);
322
323     Util::Configuration *getConfiguration() {return m_configuration;};
324
325 // ISO channel stuff
326 public:
327     signed int getAvailableBandwidth();
328     signed int allocateIsoChannelGeneric(unsigned int bandwidth);
329     signed int allocateIsoChannelCMP(nodeid_t xmit_node, int xmit_plug,
330                                      nodeid_t recv_node, int recv_plug);
331     bool freeIsoChannel(signed int channel);
332
333     IsoHandlerManager& getIsoHandlerManager() {return *m_pIsoManager;};
334 private:
335     enum EAllocType {
336         AllocFree = 0, // not allocated (by us)
337         AllocGeneric = 1, // allocated with generic functions
338         AllocCMP=2 // allocated with CMP
339     };
340
341     struct ChannelInfo {
342         int channel;
343         int bandwidth;
344         enum EAllocType alloctype;
345         nodeid_t xmit_node;
346         int xmit_plug;
347         nodeid_t recv_node;
348         int recv_plug;
349     };
350
351     // the info for the channels we manage
352     struct ChannelInfo m_channels[64];
353
354     bool unregisterIsoChannel(unsigned int c);
355     bool registerIsoChannel(unsigned int c, struct ChannelInfo cinfo);
356
357 public:
358 // FIXME: should be private, but is used to do the PCR control in GenericAVC::AvDevice
359     raw1394handle_t getHandle() {return m_handle;};
360
361 protected:
362     Util::Configuration     *m_configuration;
363
364 private:
365     bool configurationUpdated();
366
367     bool startRHThread();
368     void stopRHThread();
369     static void* rHThread( void* arg );
370
371     void printBuffer( unsigned int level, size_t length, fb_quadlet_t* buffer ) const;
372     void printBufferBytes( unsigned int level, size_t length, byte_t* buffer ) const;
373
374     static int resetHandlerLowLevel( raw1394handle_t handle,
375                                      unsigned int generation );
376     bool resetHandler( unsigned int generation );
377
378     raw1394handle_t m_handle;
379     Util::Mutex*    m_handle_lock;
380     raw1394handle_t m_resetHandle;
381     raw1394handle_t m_util_handle; // a handle for operations from the rt thread
382     int             m_port;
383     std::string     m_portName;
384
385     pthread_t       m_thread;
386     Util::Mutex*    m_RHThread_lock;
387     bool            m_threadRunning;
388
389     bool            m_realtime;
390     int             m_base_priority;
391
392     IsoHandlerManager*      m_pIsoManager;
393     CycleTimerHelper*       m_pCTRHelper;
394     bool                    m_have_new_ctr_read;
395
396     // the RT watchdog
397     Util::Watchdog*     m_pWatchdog;
398
399     typedef std::vector< Util::Functor* > reset_handler_vec_t;
400     reset_handler_vec_t m_busResetHandlers;
401
402     // unprotected variants
403     bool writeNoLock( fb_nodeid_t nodeId,
404         fb_nodeaddr_t addr,
405         size_t length,
406         fb_quadlet_t* data );
407     bool readNoLock( fb_nodeid_t nodeId,
408            fb_nodeaddr_t addr,
409            size_t length,
410            fb_quadlet_t* buffer );
411
412     // FCP transaction support
413     static int _avc_fcp_handler(raw1394handle_t handle, nodeid_t nodeid,
414                                 int response, size_t length,
415                                 unsigned char *data);
416     int handleFcpResponse(nodeid_t nodeid,
417                           int response, size_t length,
418                           unsigned char *data);
419
420     enum eFcpStatus {
421         eFS_Empty,
422         eFS_Waiting,
423         eFS_Responded,
424         eFS_Error,
425     };
426
427     struct sFcpBlock {
428         enum eFcpStatus status;
429         nodeid_t target_nodeid;
430         unsigned int request_length;
431         quadlet_t request[MAX_FCP_BLOCK_SIZE_QUADS];
432         unsigned int response_length;
433         quadlet_t response[MAX_FCP_BLOCK_SIZE_QUADS];
434     };
435     struct sFcpBlock m_fcp_block;
436
437     bool doFcpTransaction();
438     bool doFcpTransactionTry();
439
440 public:
441     void setVerboseLevel(int l);
442     void show();
443 private:
444     DECLARE_DEBUG_MODULE;
445 };
446
447 #endif // FFADO_IEEE1394SERVICE_H
Note: See TracBrowser for help on using the browser.