Clean up compiler warnings when compiling on 64-bit systems. These are mostly fixing...
[ffado.git] / libffado / src / libieee1394 / ieee1394service.h
blob612a9fd3d9603fba091e048cace541b6be65b691
1 /*
2 * Copyright (C) 2005-2008 by Daniel Wagner
3 * Copyright (C) 2005-2008 by Pieter Palmers
5 * This file is part of FFADO
6 * FFADO = Free Firewire (pro-)audio drivers for linux
8 * FFADO is based upon FreeBoB
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.
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.
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/>.
25 #ifndef FFADO_IEEE1394SERVICE_H
26 #define FFADO_IEEE1394SERVICE_H
28 #include "fbtypes.h"
29 #include "libutil/Functors.h"
30 #include "libutil/Mutex.h"
31 #include "libutil/Thread.h"
33 #include "debugmodule/debugmodule.h"
35 #include "IEC61883.h"
37 #include <libraw1394/raw1394.h>
38 #include <pthread.h>
40 #include <vector>
41 #include <string>
42 #include <stdint.h>
45 #define MAX_FCP_BLOCK_SIZE_BYTES (512)
46 #define MAX_FCP_BLOCK_SIZE_QUADS (MAX_FCP_BLOCK_SIZE_BYTES / 4)
48 class IsoHandlerManager;
49 class CycleTimerHelper;
51 namespace Util {
52 class Watchdog;
53 class Configuration;
56 class Ieee1394Service : public IEC61883 {
57 public:
58 class ARMHandler;
60 public:
61 Ieee1394Service();
62 Ieee1394Service(bool rt, int prio);
63 ~Ieee1394Service();
65 bool initialize( int port );
66 bool setThreadParameters(bool rt, int priority);
67 Util::Watchdog *getWatchdog() {return m_pWatchdog;};
69 /**
70 * @brief get number of ports (firewire adapters) in this machine
72 * @return the number of ports
74 static int detectNbPorts();
76 /**
77 * @brief get port (adapter) id
79 * @return get port (adapter) id
81 int getPort()
82 { return m_port; }
84 /**
85 * @brief get port (adapter) name
87 * @return get port (adapter) name
89 std::string getPortName()
90 { return m_portName; };
92 /**
93 * @brief get number of nodes on the bus
95 * Since the root node always has
96 * the highest node ID, this number can be used to determine that ID (it's
97 * LOCAL_BUS|(count-1)).
99 * @return the number of nodes on the bus to which the port is connected.
100 * This value can change with every bus reset.
102 int getNodeCount();
105 * @brief get the node id of the local node
107 * @note does not include the bus part (0xFFC0)
109 * @return the node id of the local node
110 * This value can change with every bus reset.
112 nodeid_t getLocalNodeId();
115 * @brief get the most recent cycle timer value (in ticks)
117 * @note Uses the most appropriate method for getting the cycle timer
118 * which is not necessarily a direct read (could be DLL)
120 uint32_t getCycleTimerTicks();
123 * @brief get the most recent cycle timer value (in CTR format)
125 * @note Uses the most appropriate method for getting the cycle timer
126 * which is not necessarily a direct read (could be DLL)
128 uint32_t getCycleTimer();
131 * @brief get the cycle timer value for a specific time instant (in ticks)
133 * @note Uses the most appropriate method for getting the cycle timer
134 * which is not necessarily a direct read (could be DLL)
136 uint32_t getCycleTimerTicks(uint64_t t);
139 * @brief get the cycle timer value for a specific time instant (in CTR format)
141 * @note Uses the most appropriate method for getting the cycle timer
142 * which is not necessarily a direct read (could be DLL)
144 uint32_t getCycleTimer(uint64_t t);
147 * @brief get the system time for a specific cycle timer value (in ticks)
148 * @note thread safe
150 uint64_t getSystemTimeForCycleTimerTicks(uint32_t ticks);
153 * @brief get the system time for a specific cycle timer value (in CTR format)
154 * @note thread safe
156 uint64_t getSystemTimeForCycleTimer(uint32_t ctr);
159 * @brief read the cycle timer value from the controller (in CTR format)
161 * @note Uses a direct method to read the value from the controller
162 * @return true if successful
164 bool readCycleTimerReg(uint32_t *cycle_timer, uint64_t *local_time);
167 * @brief provide the current system time
168 * @return
170 uint64_t getCurrentTimeAsUsecs();
173 * @brief send async read request to a node and wait for response.
175 * This does the complete transaction and will return when it's finished.
177 * @param node target node (\todo needs 0xffc0 stuff)
178 * @param addr address to read from
179 * @param length amount of data to read in quadlets
180 * @param buffer pointer to buffer where data will be saved
182 * @return true on success or false on failure (sets errno)
184 bool read( fb_nodeid_t nodeId,
185 fb_nodeaddr_t addr,
186 size_t length,
187 fb_quadlet_t* buffer );
189 bool read_quadlet( fb_nodeid_t nodeId,
190 fb_nodeaddr_t addr,
191 fb_quadlet_t* buffer );
193 bool read_octlet( fb_nodeid_t nodeId,
194 fb_nodeaddr_t addr,
195 fb_octlet_t* buffer );
198 * @brief send async write request to a node and wait for response.
200 * This does the complete transaction and will return when it's finished.
202 * @param node target node (\XXX needs 0xffc0 stuff)
203 * @param addr address to write to
204 * @param length amount of data to write in quadlets
205 * @param data pointer to data to be sent
207 * @return true on success or false on failure (sets errno)
209 bool write( fb_nodeid_t nodeId,
210 fb_nodeaddr_t addr,
211 size_t length,
212 fb_quadlet_t* data );
214 bool write_quadlet( fb_nodeid_t nodeId,
215 fb_nodeaddr_t addr,
216 fb_quadlet_t data );
218 bool write_octlet( fb_nodeid_t nodeId,
219 fb_nodeaddr_t addr,
220 fb_octlet_t data );
223 * @brief send 64-bit compare-swap lock request and wait for response.
225 * swaps the content of \ref addr with \ref swap_value , but only if
226 * the content of \ref addr equals \ref compare_with
228 * @note takes care of endiannes
230 * @param nodeId target node ID
231 * @param addr address within target node address space
232 * @param compare_with value to compare \ref addr with
233 * @param swap_value new value to put in \ref addr
234 * @param result the value (originally) in \ref addr
236 * @return true if succesful, false otherwise
238 bool lockCompareSwap64( fb_nodeid_t nodeId,
239 fb_nodeaddr_t addr,
240 fb_octlet_t compare_value,
241 fb_octlet_t swap_value,
242 fb_octlet_t* result );
245 * initiate AV/C transaction
246 * @param nodeId
247 * @param buf
248 * @param len
249 * @param resp_len
250 * @return
252 fb_quadlet_t* transactionBlock( fb_nodeid_t nodeId,
253 fb_quadlet_t* buf,
254 int len,
255 unsigned int* resp_len );
258 * close AV/C transaction.
259 * @param nodeId
260 * @param buf
261 * @param len
262 * @param resp_len
263 * @return
265 bool transactionBlockClose();
267 int getVerboseLevel();
269 bool addBusResetHandler( Util::Functor* functor );
270 bool remBusResetHandler( Util::Functor* functor );
272 void doBusReset();
273 bool waitForBusResetStormToEnd( int nb_tries, int sleep_time_ms );
276 * @brief register an AddressRangeMapping Handler
277 * @param h pointer to the handler to register
279 * @return true on success or false on failure
282 bool registerARMHandler( ARMHandler *h );
285 * @brief unregister ARM range
286 * @param h pointer to the handler to unregister
287 * @return true if successful, false otherwise
289 bool unregisterARMHandler( ARMHandler *h );
291 nodeaddr_t findFreeARMBlock( nodeaddr_t start, size_t length, size_t step );
294 * @brief get the current generation
296 * @return the current generation
298 unsigned int getGeneration() {
299 Util::MutexLockHelper lock(*m_handle_lock);
300 return raw1394_get_generation( m_handle );
304 * @brief update the current generation
306 * @return the current generation
308 void updateGeneration() {
309 Util::MutexLockHelper lock(*m_handle_lock);
310 raw1394_update_generation( m_handle, getGeneration());
314 * @brief sets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers
316 * sets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers on node
317 * nodeId such that the timeout is equal to timeout
319 * @param nodeId node to set CSR registers on
320 * @param timeout timeout in usecs
321 * @return true if successful
323 bool setSplitTimeoutUsecs(fb_nodeid_t nodeId, unsigned int timeout);
326 * @brief gets the SPLIT_TIMEOUT_X timeout value
328 * gets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers on node
329 * nodeId and recombine them into one usec value
331 * @param nodeId node to get CSR registers from
332 * @return timeout in usecs if successful, 0 else
334 int getSplitTimeoutUsecs(fb_nodeid_t nodeId);
337 * @brief use the provided configuration for this service
339 * only update the config once, before init. not thread safe,
340 * and no effect when things are already running.
342 * @param c configuration to use
343 * @return bool if this config is ok.
345 bool useConfiguration(Util::Configuration *c);
347 Util::Configuration *getConfiguration() {return m_configuration;};
350 * @brief enable or disable FCP response doublicate filtering
352 * this is use only for devices (e.g. edirol fa101) which have a
353 * buggy FCP implementation and send more then one FCP response
354 * for one request.
356 void setFCPResponseFiltering(bool enable);
358 // ISO channel stuff
359 public:
360 signed int getAvailableBandwidth();
361 signed int allocateIsoChannelGeneric(unsigned int bandwidth);
362 signed int allocateFixedIsoChannelGeneric(
363 unsigned int chan, unsigned int bandwidth);
364 signed int allocateIsoChannelCMP(nodeid_t xmit_node, int xmit_plug,
365 nodeid_t recv_node, int recv_plug);
366 bool freeIsoChannel(signed int channel);
368 IsoHandlerManager& getIsoHandlerManager() {return *m_pIsoManager;};
369 private:
370 enum EAllocType {
371 AllocFree = 0, // not allocated (by us)
372 AllocGeneric = 1, // allocated with generic functions
373 AllocCMP=2 // allocated with CMP
376 struct ChannelInfo {
377 int channel;
378 int bandwidth;
379 enum EAllocType alloctype;
380 nodeid_t xmit_node;
381 int xmit_plug;
382 nodeid_t recv_node;
383 int recv_plug;
386 // the info for the channels we manage
387 struct ChannelInfo m_channels[64];
389 bool unregisterIsoChannel(unsigned int c);
390 bool registerIsoChannel(unsigned int c, struct ChannelInfo cinfo);
392 public:
393 // FIXME: should be private, but is used to do the PCR control in GenericAVC::AvDevice
394 raw1394handle_t getHandle() {return m_handle;};
396 protected:
397 Util::Configuration *m_configuration;
399 private:
400 // this class will create a new 1394 handle
401 // and a thread that will iterate it
402 class HelperThread : public Util::RunnableInterface
404 public:
405 HelperThread(Ieee1394Service &, std::string);
406 HelperThread(Ieee1394Service &, std::string, bool rt, int prio);
407 virtual ~HelperThread();
409 raw1394handle_t get1394Handle() {return m_handle;};
410 Ieee1394Service &get1394Service() {return m_parent;};
412 virtual bool Init();
413 virtual bool Execute();
415 void setThreadParameters(bool rt, int priority);
417 bool Start();
418 bool Stop();
420 private:
421 Ieee1394Service &m_parent;
422 std::string m_name;
423 raw1394handle_t m_handle;
424 Util::Thread & m_thread;
425 bool m_iterate;
427 DECLARE_DEBUG_MODULE_REFERENCE;
430 HelperThread *m_resetHelper;
431 HelperThread *m_armHelperNormal;
432 HelperThread *m_armHelperRealtime;
434 private: // unsorted
435 bool configurationUpdated();
437 void printBuffer( unsigned int level, size_t length, fb_quadlet_t* buffer ) const;
438 void printBufferBytes( unsigned int level, size_t length, byte_t* buffer ) const;
440 static int resetHandlerLowLevel( raw1394handle_t handle,
441 unsigned int generation );
442 bool resetHandler( unsigned int generation );
444 static int armHandlerLowLevel(raw1394handle_t handle, unsigned long arm_tag,
445 byte_t request_type, unsigned int requested_length,
446 void *data);
447 bool armHandler( unsigned long arm_tag,
448 byte_t request_type, unsigned int requested_length,
449 void *data);
451 raw1394handle_t m_handle;
452 Util::Mutex* m_handle_lock;
453 raw1394handle_t m_util_handle;
454 int m_port;
455 std::string m_portName;
457 bool m_realtime;
458 int m_base_priority;
460 IsoHandlerManager* m_pIsoManager;
461 CycleTimerHelper* m_pCTRHelper;
462 bool m_have_new_ctr_read;
463 bool m_have_read_ctr_and_clock;
465 bool m_filterFCPResponse;
467 // the RT watchdog
468 Util::Watchdog* m_pWatchdog;
470 typedef std::vector< Util::Functor* > reset_handler_vec_t;
471 reset_handler_vec_t m_busResetHandlers;
473 // ARM stuff
474 arm_tag_handler_t m_default_arm_handler;
476 typedef std::vector< ARMHandler * > arm_handler_vec_t;
477 arm_handler_vec_t m_armHandlers;
479 // unprotected variants
480 bool writeNoLock( fb_nodeid_t nodeId,
481 fb_nodeaddr_t addr,
482 size_t length,
483 fb_quadlet_t* data );
484 bool readNoLock( fb_nodeid_t nodeId,
485 fb_nodeaddr_t addr,
486 size_t length,
487 fb_quadlet_t* buffer );
489 // FCP transaction support
490 static int _avc_fcp_handler(raw1394handle_t handle, nodeid_t nodeid,
491 int response, size_t length,
492 unsigned char *data);
493 int handleFcpResponse(nodeid_t nodeid,
494 int response, size_t length,
495 unsigned char *data);
497 enum eFcpStatus {
498 eFS_Empty,
499 eFS_Waiting,
500 eFS_Responded,
501 eFS_Error,
504 struct sFcpBlock {
505 enum eFcpStatus status;
506 nodeid_t target_nodeid;
507 unsigned int request_length;
508 quadlet_t request[MAX_FCP_BLOCK_SIZE_QUADS];
509 unsigned int response_length;
510 quadlet_t response[MAX_FCP_BLOCK_SIZE_QUADS];
512 struct sFcpBlock m_fcp_block;
514 bool doFcpTransaction();
515 bool doFcpTransactionTry();
517 public:
518 void setVerboseLevel(int l);
519 void show();
520 private:
521 DECLARE_DEBUG_MODULE;
523 public:
525 * @brief Class to handle AddressRangeMappings
527 * This class is intended to help with implementing
528 * address range mapping, i.e. implementing handlers
529 * that react to reads/writes of certain addresses
530 * in 1394 memory space
532 * see the _arm_ functions in raw1394.h for more insight
536 class ARMHandler {
537 public:
538 ARMHandler(Ieee1394Service &parent,
539 nodeaddr_t start, size_t length,
540 unsigned int access_rights,
541 unsigned int notification_options,
542 unsigned int client_transactions
545 virtual ~ARMHandler();
547 virtual bool handleRead(struct raw1394_arm_request *);
548 virtual bool handleWrite(struct raw1394_arm_request *);
549 virtual bool handleLock(struct raw1394_arm_request *);
551 struct raw1394_arm_response *getResponse() {return &m_response;};
553 nodeaddr_t getStart() {return m_start;};
554 size_t getLength() {return m_length;};
555 unsigned int getAccessRights() {return m_access_rights;};
556 unsigned int getNotificationOptions() {return m_notification_options;};
557 unsigned int getClientTransactions() {return m_client_transactions;};
559 byte_t *getBuffer() {return m_buffer;};
561 private:
562 Ieee1394Service &m_parent;
563 nodeaddr_t m_start;
564 size_t m_length;
565 unsigned int m_access_rights;
566 unsigned int m_notification_options;
567 unsigned int m_client_transactions;
568 protected:
569 byte_t *m_buffer;
571 struct raw1394_arm_response m_response;
573 void printBufferBytes( unsigned int level, size_t length, byte_t* buffer ) const;
574 void printRequest(struct raw1394_arm_request *arm_req);
576 DECLARE_DEBUG_MODULE_REFERENCE;
582 #endif // FFADO_IEEE1394SERVICE_H