root/trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

Revision 1995, 70.3 kB (checked in by jwoithe, 9 years ago)

Ensure the IsoHandler? disable lock is initialised regardless of which constructor is called. Its omission from these was a big oversight of mine in r1985, and probably explains the ongoing problems noted by various people in issue 306 after r1985 was committed. A big thanks to Holger Dehnhardt for lending his eyes to the problem and spotting my silly obvious error.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program 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
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "config.h"
25
26 #include "IsoHandlerManager.h"
27 #include "ieee1394service.h"
28 #include "cycletimer.h"
29 #include "libstreaming/generic/StreamProcessor.h"
30
31 #include "libutil/Atomic.h"
32 #include "libutil/PosixThread.h"
33 #include "libutil/SystemTimeSource.h"
34 #include "libutil/Watchdog.h"
35 #include "libutil/Configuration.h"
36
37 #include <cstring>
38 #include <assert.h>
39
40 IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL );
41 IMPL_DEBUG_MODULE( IsoHandlerManager::IsoTask, IsoTask, DEBUG_LEVEL_NORMAL );
42 IMPL_DEBUG_MODULE( IsoHandlerManager::IsoHandler, IsoHandler, DEBUG_LEVEL_NORMAL );
43
44 using namespace Streaming;
45
46 // --- ISO Thread --- //
47
48 IsoHandlerManager::IsoTask::IsoTask(IsoHandlerManager& manager, enum IsoHandler::EHandlerType t)
49     : m_manager( manager )
50     , m_SyncIsoHandler ( NULL )
51     , m_handlerType( t )
52     , m_running( false )
53     , m_in_busreset( false )
54     , m_activity_wait_timeout_nsec (ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS * 1000LL)
55 {
56 }
57
58 IsoHandlerManager::IsoTask::~IsoTask()
59 {
60     sem_destroy(&m_activity_semaphore);
61 }
62
63 bool
64 IsoHandlerManager::IsoTask::Init()
65 {
66     request_update = 0;
67
68     int i;
69     for (i=0; i < ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT; i++) {
70         m_IsoHandler_map_shadow[i] = NULL;
71         m_poll_fds_shadow[i].events = 0;
72     }
73     m_poll_nfds_shadow = 0;
74
75     #ifdef DEBUG
76     m_last_loop_entry = 0;
77     m_successive_short_loops = 0;
78     #endif
79
80     sem_init(&m_activity_semaphore, 0, 0);
81     m_running = true;
82     return true;
83 }
84
85 void
86 IsoHandlerManager::IsoTask::requestShadowMapUpdate()
87 {
88     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) enter\n", this);
89     INC_ATOMIC(&request_update);
90
91     // get the thread going again
92     signalActivity();
93     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) exit\n", this);
94 }
95
96 bool
97 IsoHandlerManager::IsoTask::handleBusReset()
98 {
99     bool retval = true;
100     if(!m_running) {
101         // nothing to do here
102         return true;
103     }
104     m_in_busreset = true;
105     requestShadowMapUpdate();
106
107     unsigned int i, max;
108     max = m_manager.m_IsoHandlers.size();
109     for (i = 0; i < max; i++) {
110         IsoHandler *h = m_manager.m_IsoHandlers.at(i);
111         assert(h);
112
113         // skip the handlers not intended for us
114         if(h->getType() != m_handlerType) continue;
115
116         if (!h->handleBusReset()) {
117             debugWarning("Failed to handle busreset on %p\n", h);
118             retval = false;
119         }
120     }
121
122     // re-enable processing
123     m_in_busreset = false;
124     requestShadowMapUpdate();
125     return retval;
126 }
127
128 // updates the internal stream map
129 // note that this should be executed with the guarantee that
130 // nobody will modify the parent data structures
131 void
132 IsoHandlerManager::IsoTask::updateShadowMapHelper()
133 {
134     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) updating shadow vars...\n", this);
135     // we are handling a busreset
136     if(m_in_busreset) {
137         m_poll_nfds_shadow = 0;
138         return;
139     }
140     unsigned int i, cnt, max;
141     max = m_manager.m_IsoHandlers.size();
142     m_SyncIsoHandler = NULL;
143     for (i = 0, cnt = 0; i < max; i++) {
144
145         // FIXME: This is a very crude guard against some other thread
146         // deleting handlers while this function is running.  While this
147         // didn't tend to happen with the old kernel firewire stack, delays
148         // in shutdown experienced in the new stack mean it can happen that
149         // a handler disappears during the running of this function.  This
150         // test should prevent "out of range" exceptions in most cases.
151         // However, it is racy: if the deletion happens between this
152         // conditional and the following at() call, an out of range
153         // condition can still happen.
154         if (i>=m_manager.m_IsoHandlers.size())
155             continue;
156
157         IsoHandler *h = m_manager.m_IsoHandlers.at(i);
158         assert(h);
159
160         // skip the handlers not intended for us
161         if(h->getType() != m_handlerType) continue;
162
163         // update the state of the handler
164         // FIXME: maybe this is not the best place to do this
165         // it might be better to eliminate the 'requestShadowMapUpdate'
166         // entirely and replace it with a mechanism that implements all
167         // actions on the m_manager.m_IsoHandlers in the loop
168         h->updateState();
169
170         // rebuild the map
171         if (h->isEnabled()) {
172             m_IsoHandler_map_shadow[cnt] = h;
173             m_poll_fds_shadow[cnt].fd = h->getFileDescriptor();
174             m_poll_fds_shadow[cnt].revents = 0;
175             m_poll_fds_shadow[cnt].events = POLLIN;
176             cnt++;
177             // FIXME: need a more generic approach here
178             if(   m_SyncIsoHandler == NULL
179                && h->getType() == IsoHandler::eHT_Transmit) {
180                 m_SyncIsoHandler = h;
181             }
182
183             debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) %s handler %p added\n",
184                                               this, h->getTypeString(), h);
185         } else {
186             debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) %s handler %p skipped (disabled)\n",
187                                               this, h->getTypeString(), h);
188         }
189         if(cnt > ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT) {
190             debugWarning("Too much ISO Handlers in thread...\n");
191             break;
192         }
193     }
194
195     // FIXME: need a more generic approach here
196     // if there are no active transmit handlers,
197     // use the first receive handler
198     if(   m_SyncIsoHandler == NULL
199        && m_poll_nfds_shadow) {
200         m_SyncIsoHandler = m_IsoHandler_map_shadow[0];
201     }
202     m_poll_nfds_shadow = cnt;
203     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) updated shadow vars...\n", this);
204 }
205
206 bool
207 IsoHandlerManager::IsoTask::Execute()
208 {
209     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,
210                 "(%p, %s) Execute\n",
211                 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
212     int err;
213     unsigned int i;
214     unsigned int m_poll_timeout = 10;
215
216     #ifdef DEBUG
217     uint64_t now = Util::SystemTimeSource::getCurrentTimeAsUsecs();
218     int diff = now - m_last_loop_entry;
219     if(diff < 100) {
220         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE,
221                            "(%p, %s) short loop detected (%d usec), cnt: %d\n",
222                            this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),
223                            diff, m_successive_short_loops);
224         m_successive_short_loops++;
225         if(m_successive_short_loops > 10000) {
226             debugError("Shutting down runaway thread\n");
227             m_running = false;
228             return false;
229         }
230     } else {
231         // reset the counter
232         m_successive_short_loops = 0;
233     }
234     m_last_loop_entry = now;
235     #endif
236
237     // if some other thread requested a shadow map update, do it
238     if(request_update) {
239         updateShadowMapHelper();
240         DEC_ATOMIC(&request_update); // ack the update
241         assert(request_update >= 0);
242     }
243
244     // bypass if no handlers are registered
245     if (m_poll_nfds_shadow == 0) {
246         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE,
247                            "(%p, %s) bypass iterate since no handlers to poll\n",
248                            this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
249         usleep(m_poll_timeout * 1000);
250         return true;
251     }
252
253     // FIXME: what can happen is that poll() returns, but not all clients are
254     // ready. there might be some busy waiting behavior that still has to be solved.
255
256     // setup the poll here
257     // we should prevent a poll() where no events are specified, since that will only time-out
258     bool no_one_to_poll = true;
259     while(no_one_to_poll) {
260         for (i = 0; i < m_poll_nfds_shadow; i++) {
261             short events = 0;
262             IsoHandler *h = m_IsoHandler_map_shadow[i];
263             // we should only poll on a transmit handler
264             // that has a client that is ready to send
265             // something. Otherwise it will end up in
266             // busy wait looping since the packet function
267             // will defer processing (also avoids the
268             // AGAIN problem)
269             if (h->canIterateClient()) {
270                 events = POLLIN | POLLPRI;
271                 no_one_to_poll = false;
272             }
273             m_poll_fds_shadow[i].events = events;
274         }
275
276         if(no_one_to_poll) {
277             debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
278                         "(%p, %s) No one to poll, waiting for something to happen\n",
279                         this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
280             // wait for something to happen
281             switch(waitForActivity()) {
282                 case IsoHandlerManager::IsoTask::eAR_Error:
283                     debugError("Error while waiting for activity\n");
284                     return false;
285                 case IsoHandlerManager::IsoTask::eAR_Interrupted:
286                     // FIXME: what to do here?
287                     debugWarning("Interrupted while waiting for activity\n");
288                     break;
289                 case IsoHandlerManager::IsoTask::eAR_Timeout:
290                     // FIXME: what to do here?
291                     debugWarning("Timeout while waiting for activity\n");
292                     no_one_to_poll = false; // exit the loop to be able to detect failing handlers
293                     break;
294                 case IsoHandlerManager::IsoTask::eAR_Activity:
295                     // do nothing
296                     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
297                                        "(%p, %s) something happened\n",
298                                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
299                     break;
300             }
301         }
302     }
303
304     // Use a shadow map of the fd's such that we don't have to update
305     // the fd map everytime we run poll().
306     err = poll (m_poll_fds_shadow, m_poll_nfds_shadow, m_poll_timeout);
307     uint32_t ctr_at_poll_return = m_manager.get1394Service().getCycleTimer();
308
309     if (err < 0) {
310         if (errno == EINTR) {
311             debugOutput(DEBUG_LEVEL_VERBOSE, "Ignoring poll return due to signal\n");
312             return true;
313         }
314         debugFatal("poll error: %s\n", strerror (errno));
315         m_running = false;
316         return false;
317     }
318
319     // find handlers that have died
320     uint64_t ctr_at_poll_return_ticks = CYCLE_TIMER_TO_TICKS(ctr_at_poll_return);
321     bool handler_died = false;
322     for (i = 0; i < m_poll_nfds_shadow; i++) {
323         // figure out if a handler has died
324
325         // this is the time of the last packet we saw in the iterate() handler
326         uint32_t last_packet_seen = m_IsoHandler_map_shadow[i]->getLastPacketTime();
327         if (last_packet_seen == 0xFFFFFFFF) {
328             // this was not iterated yet, so can't be dead
329             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
330                         "(%p, %s) handler %d didn't see any packets yet\n",
331                         this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), i);
332             continue;
333         }
334
335         uint64_t last_packet_seen_ticks = CYCLE_TIMER_TO_TICKS(last_packet_seen);
336         // we use a relatively large value to distinguish between "death" and xrun
337         int64_t max_diff_ticks = TICKS_PER_SECOND * 2;
338         int64_t measured_diff_ticks = diffTicks(ctr_at_poll_return_ticks, last_packet_seen_ticks);
339
340         debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
341                            "(%p, %s) check handler %d: diff = %"PRId64", max = %"PRId64", now: %08X, last: %08X\n",
342                            this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),
343                            i, measured_diff_ticks, max_diff_ticks, ctr_at_poll_return, last_packet_seen);
344         if(measured_diff_ticks > max_diff_ticks) {
345             debugFatal("(%p, %s) Handler died: now: %08X, last: %08X, diff: %"PRId64" (max: %"PRId64")\n",
346                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),
347                        ctr_at_poll_return, last_packet_seen, measured_diff_ticks, max_diff_ticks);
348             m_IsoHandler_map_shadow[i]->notifyOfDeath();
349             handler_died = true;
350         }
351     }
352
353     if(handler_died) {
354         m_running = false;
355         return false; // one or more handlers have died
356     }
357
358     // iterate the handlers
359     for (i = 0; i < m_poll_nfds_shadow; i++) {
360         #ifdef DEBUG
361         if(m_poll_fds_shadow[i].revents) {
362             debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
363                         "(%p, %s) received events: %08X for (%d/%d, %p, %s)\n",
364                         this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),
365                         m_poll_fds_shadow[i].revents,
366                         i, m_poll_nfds_shadow,
367                         m_IsoHandler_map_shadow[i],
368                         m_IsoHandler_map_shadow[i]->getTypeString());
369         }
370         #endif
371
372         // if we get here, it means two things:
373         // 1) the kernel can accept or provide packets (poll returned POLLIN)
374         // 2) the client can provide or accept packets (since we enabled polling)
375         if(m_poll_fds_shadow[i].revents & (POLLIN)) {
376             m_IsoHandler_map_shadow[i]->iterate(ctr_at_poll_return);
377         } else {
378             // there might be some error condition
379             if (m_poll_fds_shadow[i].revents & POLLERR) {
380                 debugWarning("(%p) error on fd for %d\n", this, i);
381             }
382             if (m_poll_fds_shadow[i].revents & POLLHUP) {
383                 debugWarning("(%p) hangup on fd for %d\n", this, i);
384             }
385         }
386     }
387     return true;
388 }
389
390 enum IsoHandlerManager::IsoTask::eActivityResult
391 IsoHandlerManager::IsoTask::waitForActivity()
392 {
393     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
394                        "(%p, %s) waiting for activity\n",
395                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
396     struct timespec ts;
397     int result;
398
399     if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
400         debugError("clock_gettime failed\n");
401         return eAR_Error;
402     }
403
404     ts.tv_nsec += m_activity_wait_timeout_nsec;
405     while(ts.tv_nsec >= 1000000000LL) {
406         ts.tv_sec += 1;
407         ts.tv_nsec -= 1000000000LL;
408     }
409
410     result = sem_timedwait(&m_activity_semaphore, &ts);
411
412     if(result != 0) {
413         if (errno == ETIMEDOUT) {
414             debugOutput(DEBUG_LEVEL_VERBOSE,
415                         "(%p) sem_timedwait() timed out (result=%d)\n",
416                         this, result);
417             return eAR_Timeout;
418         } else if (errno == EINTR) {
419             debugOutput(DEBUG_LEVEL_VERBOSE,
420                         "(%p) sem_timedwait() interrupted by signal (result=%d)\n",
421                         this, result);
422             return eAR_Interrupted;
423         } else if (errno == EINVAL) {
424             debugError("(%p) sem_timedwait error (result=%d errno=EINVAL)\n",
425                         this, result);
426             debugError("(%p) timeout_nsec=%lld ts.sec=%"PRId64" ts.nsec=%"PRId64"\n",
427                        this, m_activity_wait_timeout_nsec,
428                        (int64_t)ts.tv_sec, (int64_t)ts.tv_nsec);
429             return eAR_Error;
430         } else {
431             debugError("(%p) sem_timedwait error (result=%d errno=%d)\n",
432                         this, result, errno);
433             debugError("(%p) timeout_nsec=%lld ts.sec=%"PRId64" ts.nsec=%"PRId64"\n",
434                        this, m_activity_wait_timeout_nsec,
435                        (int64_t)ts.tv_sec, (int64_t)ts.tv_nsec);
436             return eAR_Error;
437         }
438     }
439
440     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,
441                 "(%p, %s) got activity\n",
442                 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
443     return eAR_Activity;
444 }
445
446 void
447 IsoHandlerManager::IsoTask::signalActivity()
448 {
449     // signal the activity cond var
450     sem_post(&m_activity_semaphore);
451     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,
452                 "(%p, %s) activity\n",
453                 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
454 }
455
456 void IsoHandlerManager::IsoTask::setVerboseLevel(int i) {
457     setDebugLevel(i);
458     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i );
459 }
460
461 // -- the ISO handler manager -- //
462 IsoHandlerManager::IsoHandlerManager(Ieee1394Service& service)
463    : m_State(E_Created)
464    , m_service( service )
465    , m_realtime(false), m_priority(0)
466    , m_IsoThreadTransmit ( NULL )
467    , m_IsoTaskTransmit ( NULL )
468    , m_IsoThreadReceive ( NULL )
469    , m_IsoTaskReceive ( NULL )
470 {
471 }
472
473 IsoHandlerManager::IsoHandlerManager(Ieee1394Service& service, bool run_rt, int rt_prio)
474    : m_State(E_Created)
475    , m_service( service )
476    , m_realtime(run_rt), m_priority(rt_prio)
477    , m_IsoThreadTransmit ( NULL )
478    , m_IsoTaskTransmit ( NULL )
479    , m_IsoThreadReceive ( NULL )
480    , m_IsoTaskReceive ( NULL )
481    , m_MissedCyclesOK ( false )
482 {
483 }
484
485 IsoHandlerManager::~IsoHandlerManager()
486 {
487     stopHandlers();
488     pruneHandlers();
489     if(m_IsoHandlers.size() > 0) {
490         debugError("Still some handlers in use\n");
491     }
492     if (m_IsoThreadTransmit) {
493         m_IsoThreadTransmit->Stop();
494         delete m_IsoThreadTransmit;
495     }
496     if (m_IsoThreadReceive) {
497         m_IsoThreadReceive->Stop();
498         delete m_IsoThreadReceive;
499     }
500     if (m_IsoTaskTransmit) {
501         delete m_IsoTaskTransmit;
502     }
503     if (m_IsoTaskReceive) {
504         delete m_IsoTaskReceive;
505     }
506 }
507
508 bool
509 IsoHandlerManager::handleBusReset()
510 {
511     debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n");
512     // A few things can happen on bus reset:
513     // 1) no devices added/removed => streams are still valid, but might have to be restarted
514     // 2) a device was removed => some streams become invalid
515     // 3) a device was added => same as 1, new device is ignored
516     if (!m_IsoTaskTransmit) {
517         debugError("No xmit task\n");
518         return false;
519     }
520     if (!m_IsoTaskReceive) {
521         debugError("No receive task\n");
522         return false;
523     }
524     if (!m_IsoTaskTransmit->handleBusReset()) {
525         debugWarning("could no handle busreset on xmit\n");
526     }
527     if (!m_IsoTaskReceive->handleBusReset()) {
528         debugWarning("could no handle busreset on recv\n");
529     }
530     return true;
531 }
532
533 void
534 IsoHandlerManager::requestShadowMapUpdate()
535 {
536     if(m_IsoTaskTransmit) m_IsoTaskTransmit->requestShadowMapUpdate();
537     if(m_IsoTaskReceive) m_IsoTaskReceive->requestShadowMapUpdate();
538 }
539
540 bool
541 IsoHandlerManager::setThreadParameters(bool rt, int priority) {
542     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) switch to: (rt=%d, prio=%d)...\n", this, rt, priority);
543     if (priority > THREAD_MAX_RTPRIO) priority = THREAD_MAX_RTPRIO; // cap the priority
544     if (priority < THREAD_MIN_RTPRIO) priority = THREAD_MIN_RTPRIO; // cap the priority
545     m_realtime = rt;
546     m_priority = priority;
547
548     // grab the options from the parent
549     Util::Configuration *config = m_service.getConfiguration();
550     int ihm_iso_prio_increase = ISOHANDLERMANAGER_ISO_PRIO_INCREASE;
551     int ihm_iso_prio_increase_xmit = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT;
552     int ihm_iso_prio_increase_recv = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV;
553     if(config) {
554         config->getValueForSetting("ieee1394.isomanager.prio_increase", ihm_iso_prio_increase);
555         config->getValueForSetting("ieee1394.isomanager.prio_increase_xmit", ihm_iso_prio_increase_xmit);
556         config->getValueForSetting("ieee1394.isomanager.prio_increase_recv", ihm_iso_prio_increase_recv);
557     }
558
559     if (m_IsoThreadTransmit) {
560         if (m_realtime) {
561             m_IsoThreadTransmit->AcquireRealTime(m_priority
562                                                  + ihm_iso_prio_increase
563                                                  + ihm_iso_prio_increase_xmit);
564         } else {
565             m_IsoThreadTransmit->DropRealTime();
566         }
567     }
568     if (m_IsoThreadReceive) {
569         if (m_realtime) {
570             m_IsoThreadReceive->AcquireRealTime(m_priority
571                                                 + ihm_iso_prio_increase
572                                                 + ihm_iso_prio_increase_recv);
573         } else {
574             m_IsoThreadReceive->DropRealTime();
575         }
576     }
577
578     return true;
579 }
580
581 bool IsoHandlerManager::init()
582 {
583     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing ISO manager %p...\n", this);
584     // check state
585     if(m_State != E_Created) {
586         debugError("Manager already initialized...\n");
587         return false;
588     }
589
590     // grab the options from the parent
591     Util::Configuration *config = m_service.getConfiguration();
592     int ihm_iso_prio_increase = ISOHANDLERMANAGER_ISO_PRIO_INCREASE;
593     int ihm_iso_prio_increase_xmit = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT;
594     int ihm_iso_prio_increase_recv = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV;
595     int64_t isotask_activity_timeout_usecs = ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS;
596     if(config) {
597         config->getValueForSetting("ieee1394.isomanager.prio_increase", ihm_iso_prio_increase);
598         config->getValueForSetting("ieee1394.isomanager.prio_increase_xmit", ihm_iso_prio_increase_xmit);
599         config->getValueForSetting("ieee1394.isomanager.prio_increase_recv", ihm_iso_prio_increase_recv);
600         config->getValueForSetting("ieee1394.isomanager.isotask_activity_timeout_usecs", isotask_activity_timeout_usecs);
601     }
602
603     // create threads to iterate our ISO handlers
604     debugOutput( DEBUG_LEVEL_VERBOSE, "Create iso thread for %p transmit...\n", this);
605     m_IsoTaskTransmit = new IsoTask( *this, IsoHandler::eHT_Transmit );
606     if(!m_IsoTaskTransmit) {
607         debugFatal("No task\n");
608         return false;
609     }
610     m_IsoTaskTransmit->setVerboseLevel(getDebugLevel());
611     m_IsoTaskTransmit->m_activity_wait_timeout_nsec = isotask_activity_timeout_usecs * 1000LL;
612     m_IsoThreadTransmit = new Util::PosixThread(m_IsoTaskTransmit, "ISOXMT", m_realtime,
613                                                 m_priority + ihm_iso_prio_increase
614                                                 + ihm_iso_prio_increase_xmit,
615                                                 PTHREAD_CANCEL_DEFERRED);
616
617     if(!m_IsoThreadTransmit) {
618         debugFatal("No thread\n");
619         return false;
620     }
621     m_IsoThreadTransmit->setVerboseLevel(getDebugLevel());
622
623     debugOutput( DEBUG_LEVEL_VERBOSE, "Create iso thread for %p receive...\n", this);
624     m_IsoTaskReceive = new IsoTask( *this, IsoHandler::eHT_Receive );
625     if(!m_IsoTaskReceive) {
626         debugFatal("No task\n");
627         return false;
628     }
629     m_IsoTaskReceive->setVerboseLevel(getDebugLevel());
630     m_IsoThreadReceive = new Util::PosixThread(m_IsoTaskReceive, "ISORCV", m_realtime,
631                                                m_priority + ihm_iso_prio_increase
632                                                + ihm_iso_prio_increase_recv,
633                                                PTHREAD_CANCEL_DEFERRED);
634
635     if(!m_IsoThreadReceive) {
636         debugFatal("No thread\n");
637         return false;
638     }
639     m_IsoThreadReceive->setVerboseLevel(getDebugLevel());
640     // register the thread with the RT watchdog
641     Util::Watchdog *watchdog = m_service.getWatchdog();
642     if(watchdog) {
643         if(!watchdog->registerThread(m_IsoThreadTransmit)) {
644             debugWarning("could not register iso transmit thread with watchdog\n");
645         }
646         if(!watchdog->registerThread(m_IsoThreadReceive)) {
647             debugWarning("could not register iso receive thread with watchdog\n");
648         }
649     } else {
650         debugWarning("could not find valid watchdog\n");
651     }
652
653     if (m_IsoThreadTransmit->Start() != 0) {
654         debugFatal("Could not start ISO Transmit thread\n");
655         return false;
656     }
657     if (m_IsoThreadReceive->Start() != 0) {
658         debugFatal("Could not start ISO Receive thread\n");
659         return false;
660     }
661
662     m_State=E_Running;
663     return true;
664 }
665
666 void
667 IsoHandlerManager::signalActivityTransmit()
668 {
669     assert(m_IsoTaskTransmit);
670     m_IsoTaskTransmit->signalActivity();
671 }
672
673 void
674 IsoHandlerManager::signalActivityReceive()
675 {
676     assert(m_IsoTaskReceive);
677     m_IsoTaskReceive->signalActivity();
678 }
679
680 bool IsoHandlerManager::registerHandler(IsoHandler *handler)
681 {
682     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
683     assert(handler);
684     handler->setVerboseLevel(getDebugLevel());
685     m_IsoHandlers.push_back(handler);
686     requestShadowMapUpdate();
687     return true;
688 }
689
690 bool IsoHandlerManager::unregisterHandler(IsoHandler *handler)
691 {
692     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
693     assert(handler);
694
695     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
696       it != m_IsoHandlers.end();
697       ++it )
698     {
699         if ( *it == handler ) {
700             m_IsoHandlers.erase(it);
701             requestShadowMapUpdate();
702             return true;
703         }
704     }
705     debugFatal("Could not find handler (%p)\n", handler);
706     return false; //not found
707 }
708
709 /**
710  * Registers an StreamProcessor with the IsoHandlerManager.
711  *
712  * If nescessary, an IsoHandler is created to handle this stream.
713  * Once an StreamProcessor is registered to the handler, it will be included
714  * in the ISO streaming cycle (i.e. receive/transmit of it will occur).
715  *
716  * @param stream the stream to register
717  * @return true if registration succeeds
718  *
719  * \todo : currently there is a one-to-one mapping
720  *        between streams and handlers, this is not ok for
721  *        multichannel receive
722  */
723 bool IsoHandlerManager::registerStream(StreamProcessor *stream)
724 {
725     debugOutput( DEBUG_LEVEL_VERBOSE, "Registering %s stream %p\n", stream->getTypeString(), stream);
726     assert(stream);
727
728     IsoHandler* h = NULL;
729
730     // make sure the stream isn't already attached to a handler
731     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
732       it != m_IsoHandlers.end();
733       ++it )
734     {
735         if((*it)->isStreamRegistered(stream)) {
736             debugError( "stream already registered!\n");
737             return false;
738         }
739     }
740
741     // clean up all handlers that aren't used
742     pruneHandlers();
743
744     // allocate a handler for this stream
745     if (stream->getType()==StreamProcessor::ePT_Receive) {
746         // grab the options from the parent
747         Util::Configuration *config = m_service.getConfiguration();
748         int receive_mode_setting = DEFAULT_ISO_RECEIVE_MODE;
749         int bufferfill_mode_threshold = BUFFERFILL_MODE_THRESHOLD;
750         int min_interrupts_per_period = MINIMUM_INTERRUPTS_PER_PERIOD;
751         int max_nb_buffers_recv = MAX_RECV_NB_BUFFERS;
752         int min_packetsize_recv = MIN_RECV_PACKET_SIZE;
753         if(config) {
754             config->getValueForSetting("ieee1394.isomanager.iso_receive_mode", receive_mode_setting);
755             config->getValueForSetting("ieee1394.isomanager.bufferfill_mode_threshold", bufferfill_mode_threshold);
756             config->getValueForSetting("ieee1394.isomanager.min_interrupts_per_period", min_interrupts_per_period);
757             config->getValueForSetting("ieee1394.isomanager.max_nb_buffers_recv", max_nb_buffers_recv);
758             config->getValueForSetting("ieee1394.isomanager.min_packetsize_recv", min_packetsize_recv);
759         }
760
761         // setup the optimal parameters for the raw1394 ISO buffering
762         unsigned int packets_per_period = stream->getPacketsPerPeriod();
763         // reserve space for the 1394 header too (might not be necessary)
764         unsigned int max_packet_size = stream->getMaxPacketSize() + 8;
765         unsigned int page_size = getpagesize();
766
767         enum raw1394_iso_dma_recv_mode receive_mode =
768                 RAW1394_DMA_PACKET_PER_BUFFER;
769         switch(receive_mode_setting) {
770             case 0:
771                 if(packets_per_period < (unsigned)bufferfill_mode_threshold) {
772                     debugOutput( DEBUG_LEVEL_VERBOSE, "Using packet-per-buffer mode (auto) [%d, %d]\n",
773                                  packets_per_period, bufferfill_mode_threshold);
774                     receive_mode = RAW1394_DMA_PACKET_PER_BUFFER;
775                 } else {
776                     debugOutput( DEBUG_LEVEL_VERBOSE, "Using bufferfill mode (auto) [%d, %d]\n",
777                                  packets_per_period, bufferfill_mode_threshold);
778                     receive_mode = RAW1394_DMA_BUFFERFILL;
779                 }
780                 break;
781             case 1:
782                 debugOutput( DEBUG_LEVEL_VERBOSE, "Using packet-per-buffer mode (config)\n");
783                 receive_mode = RAW1394_DMA_PACKET_PER_BUFFER;
784                 break;
785             case 2:
786                 debugOutput( DEBUG_LEVEL_VERBOSE, "Using bufferfill mode (config)\n");
787                 receive_mode = RAW1394_DMA_BUFFERFILL;
788                 break;
789             default: debugWarning("Bogus receive mode setting in config: %d\n", receive_mode_setting);
790         }
791
792         // Ensure we don't request a packet size bigger than the
793         // kernel-enforced maximum which is currently 1 page.
794         // NOTE: PP: this is not really true AFAICT
795         if (max_packet_size > page_size) {
796             debugError("max packet size (%u) > page size (%u)\n", max_packet_size, page_size);
797             return false;
798         }
799         if (max_packet_size < (unsigned)min_packetsize_recv) {
800             debugError("min packet size (%u) < MIN_RECV_PACKET_SIZE (%u), using min value\n",
801                        max_packet_size, min_packetsize_recv);
802             max_packet_size = min_packetsize_recv;
803         }
804
805         // apparently a too small value causes issues too
806         if(max_packet_size < 200) max_packet_size = 200;
807
808         // the interrupt/wakeup interval prediction of raw1394 is a mess...
809         int irq_interval = (packets_per_period-1) / min_interrupts_per_period;
810         if(irq_interval <= 0) irq_interval=1;
811
812         // the receive buffer size doesn't matter for the latency,
813         // it does seem to be confined to a certain region for correct
814         // operation. However it is not clear how many.
815         int buffers = max_nb_buffers_recv;
816
817         // ensure at least 2 hardware interrupts per ISO buffer wraparound
818         if(irq_interval > buffers/2) {
819             irq_interval = buffers/2;
820         }
821
822         // create the actual handler
823         debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoRecvHandler\n");
824         h = new IsoHandler(*this, IsoHandler::eHT_Receive,
825                            buffers, max_packet_size, irq_interval);
826
827         if(!h) {
828             debugFatal("Could not create IsoRecvHandler\n");
829             return false;
830         }
831
832         h->setReceiveMode(receive_mode);
833
834     } else if (stream->getType()==StreamProcessor::ePT_Transmit) {
835         // grab the options from the parent
836         Util::Configuration *config = m_service.getConfiguration();
837         int min_interrupts_per_period = MINIMUM_INTERRUPTS_PER_PERIOD;
838         int max_nb_buffers_xmit = MAX_XMIT_NB_BUFFERS;
839         int max_packetsize_xmit = MAX_XMIT_PACKET_SIZE;
840         int min_packetsize_xmit = MIN_XMIT_PACKET_SIZE;
841         if(config) {
842             config->getValueForSetting("ieee1394.isomanager.min_interrupts_per_period", min_interrupts_per_period);
843             config->getValueForSetting("ieee1394.isomanager.max_nb_buffers_xmit", max_nb_buffers_xmit);
844             config->getValueForSetting("ieee1394.isomanager.max_packetsize_xmit", max_packetsize_xmit);
845             config->getValueForSetting("ieee1394.isomanager.min_packetsize_xmit", min_packetsize_xmit);
846         }
847
848         // setup the optimal parameters for the raw1394 ISO buffering
849         // reserve space for the 1394 header too (might not be necessary)
850         unsigned int max_packet_size = stream->getMaxPacketSize() + 8;
851
852         if (max_packet_size > (unsigned)max_packetsize_xmit) {
853             debugError("max packet size (%u) > MAX_XMIT_PACKET_SIZE (%u)\n",
854                        max_packet_size, max_packetsize_xmit);
855             return false;
856         }
857         if (max_packet_size < (unsigned)min_packetsize_xmit) {
858             debugError("min packet size (%u) < MIN_XMIT_PACKET_SIZE (%u), using min value\n",
859                        max_packet_size, min_packetsize_xmit);
860             max_packet_size = min_packetsize_xmit;
861         }
862
863         int buffers = max_nb_buffers_xmit;
864         unsigned int packets_per_period = stream->getPacketsPerPeriod();
865
866         int irq_interval = (packets_per_period-1) / min_interrupts_per_period;
867         if(irq_interval <= 0) irq_interval=1;
868         // ensure at least 2 hardware interrupts per ISO buffer wraparound
869         if(irq_interval > buffers/2) {
870             irq_interval = buffers/2;
871         }
872
873         debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoXmitHandler\n");
874
875         // create the actual handler
876         h = new IsoHandler(*this, IsoHandler::eHT_Transmit,
877                            buffers, max_packet_size, irq_interval);
878
879         if(!h) {
880             debugFatal("Could not create IsoXmitHandler\n");
881             return false;
882         }
883
884     } else {
885         debugFatal("Bad stream type\n");
886         return false;
887     }
888
889     h->setVerboseLevel(getDebugLevel());
890
891     // register the stream with the handler
892     if(!h->registerStream(stream)) {
893         debugFatal("Could not register receive stream with handler\n");
894         return false;
895     }
896
897     // register the handler with the manager
898     if(!registerHandler(h)) {
899         debugFatal("Could not register receive handler with manager\n");
900         return false;
901     }
902     debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n", stream, h);
903
904     m_StreamProcessors.push_back(stream);
905     debugOutput( DEBUG_LEVEL_VERBOSE, " %zd streams, %zd handlers registered\n",
906                                       m_StreamProcessors.size(), m_IsoHandlers.size());
907     return true;
908 }
909
910 bool IsoHandlerManager::unregisterStream(StreamProcessor *stream)
911 {
912     debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering %s stream %p\n", stream->getTypeString(), stream);
913     assert(stream);
914
915     // make sure the stream isn't attached to a handler anymore
916     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
917       it != m_IsoHandlers.end();
918       ++it )
919     {
920         if((*it)->isStreamRegistered(stream)) {
921             if(!(*it)->unregisterStream(stream)) {
922                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not unregister stream (%p) from handler (%p)...\n",stream,*it);
923                 return false;
924             }
925             debugOutput( DEBUG_LEVEL_VERBOSE, " unregistered stream (%p) from handler (%p)...\n",stream,*it);
926         }
927     }
928
929     // clean up all handlers that aren't used
930     pruneHandlers();
931
932     // remove the stream from the registered streams list
933     for ( StreamProcessorVectorIterator it = m_StreamProcessors.begin();
934       it != m_StreamProcessors.end();
935       ++it )
936     {
937         if ( *it == stream ) {
938             m_StreamProcessors.erase(it);
939             debugOutput( DEBUG_LEVEL_VERBOSE, " deleted stream (%p) from list...\n", *it);
940             return true;
941         }
942     }
943     return false; //not found
944 }
945
946 /**
947  * @brief unregister a handler from the manager
948  * @note called without the lock held.
949  */
950 void IsoHandlerManager::pruneHandlers() {
951     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
952     IsoHandlerVector toUnregister;
953
954     // find all handlers that are not in use
955     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
956           it != m_IsoHandlers.end();
957           ++it )
958     {
959         if(!((*it)->inUse())) {
960             debugOutput( DEBUG_LEVEL_VERBOSE, " handler (%p) not in use\n",*it);
961             toUnregister.push_back(*it);
962         }
963     }
964     // delete them
965     for ( IsoHandlerVectorIterator it = toUnregister.begin();
966           it != toUnregister.end();
967           ++it )
968     {
969         unregisterHandler(*it);
970
971         debugOutput( DEBUG_LEVEL_VERBOSE, " deleting handler (%p)\n",*it);
972
973         // Now the handler's been unregistered it won't be reused
974         // again.  Therefore it really needs to be formally deleted
975         // to free up the raw1394 handle.  Otherwise things fall
976         // apart after several xrun recoveries as the system runs
977         // out of resources to support all the disused but still
978         // allocated raw1394 handles.  At least this is the current
979         // theory as to why we end up with "memory allocation"
980         // failures after several Xrun recoveries.
981         delete *it;
982     }
983 }
984
985 int
986 IsoHandlerManager::getPacketLatencyForStream(Streaming::StreamProcessor *stream) {
987     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
988       it != m_IsoHandlers.end();
989       ++it )
990     {
991         if((*it)->isStreamRegistered(stream)) {
992             return (*it)->getIrqInterval();
993         }
994     }
995     debugError("Stream %p has no attached handler\n", stream);
996     return 0;
997 }
998
999 IsoHandlerManager::IsoHandler *
1000 IsoHandlerManager::getHandlerForStream(Streaming::StreamProcessor *stream) {
1001     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1002       it != m_IsoHandlers.end();
1003       ++it )
1004     {
1005         if((*it)->isStreamRegistered(stream)) {
1006             return (*it);
1007         }
1008     }
1009     debugError("Stream %p has no attached handler\n", stream);
1010     return NULL;
1011 }
1012
1013 void
1014 IsoHandlerManager::dumpInfoForStream(Streaming::StreamProcessor *stream)
1015 {
1016     IsoHandler *h = getHandlerForStream(stream);
1017     if (h) {
1018         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Packets, Dropped, Skipped : %d, %d, %d\n",
1019                             h->m_packets, h->m_dropped, h->m_skipped);
1020     } else {
1021         debugError("No handler for stream %p??\n", stream);
1022     }
1023 }
1024
1025 void IsoHandlerManager::setIsoStartCycleForStream(Streaming::StreamProcessor *stream, signed int cycle) {
1026     // Permit the direct manipulation of the m_switch_on_cycle field from
1027     // the stream's handler.  This is usually used to set it to -1 so the
1028     // kernel (at least with the ieee1394 stack) starts the streaming as
1029     // soon as possible, something that is required for some interfaces (eg:
1030     // RME).  Note that as of 20 Dec 2010 it seems that ordinarily
1031     // m_switch_on_cycle remains fixed at 0 (its initialised value) because
1032     // requestEnable() doesn't set it.  This allows the override configured
1033     // by this function to take effect.
1034     IsoHandler *h = getHandlerForStream(stream);
1035     h->setIsoStartCycle(cycle);
1036 }
1037
1038 bool
1039 IsoHandlerManager::startHandlerForStream(Streaming::StreamProcessor *stream) {
1040     return startHandlerForStream(stream, -1);
1041 }
1042
1043 bool
1044 IsoHandlerManager::startHandlerForStream(Streaming::StreamProcessor *stream, int cycle) {
1045     // check state
1046     if(m_State != E_Running) {
1047         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
1048         return false;
1049     }
1050     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1051       it != m_IsoHandlers.end();
1052       ++it )
1053     {
1054         if((*it)->isStreamRegistered(stream)) {
1055             debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler %p for stream %p\n", *it, stream);
1056             if(!(*it)->requestEnable(cycle)) {
1057                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not request enable for handler %p)\n",*it);
1058                 return false;
1059             }
1060
1061             if((*it)->getType() == IsoHandler::eHT_Transmit) {
1062                 m_IsoTaskTransmit->requestShadowMapUpdate();
1063             } else {
1064                 m_IsoTaskReceive->requestShadowMapUpdate();
1065             }
1066
1067             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " requested enable for handler %p\n", *it);
1068             return true;
1069         }
1070     }
1071     debugError("Stream %p has no attached handler\n", stream);
1072     return false;
1073 }
1074
1075 bool
1076 IsoHandlerManager::stopHandlerForStream(Streaming::StreamProcessor *stream) {
1077     // check state
1078     if(m_State != E_Running) {
1079         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
1080         return false;
1081     }
1082     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1083       it != m_IsoHandlers.end();
1084       ++it )
1085     {
1086         if((*it)->isStreamRegistered(stream)) {
1087             debugOutput( DEBUG_LEVEL_VERBOSE, " stopping handler %p for stream %p\n", *it, stream);
1088             if(!(*it)->requestDisable()) {
1089                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not request disable for handler %p\n",*it);
1090                 return false;
1091             }
1092
1093             if((*it)->getType() == IsoHandler::eHT_Transmit) {
1094                 m_IsoTaskTransmit->requestShadowMapUpdate();
1095             } else {
1096                 m_IsoTaskReceive->requestShadowMapUpdate();
1097             }
1098
1099             debugOutput(DEBUG_LEVEL_VERBOSE, " requested disable for handler %p\n", *it);
1100             return true;
1101         }
1102     }
1103     debugError("Stream %p has no attached handler\n", stream);
1104     return false;
1105 }
1106
1107 bool IsoHandlerManager::stopHandlers() {
1108     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
1109
1110     // check state
1111     if(m_State != E_Running) {
1112         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
1113         return false;
1114     }
1115
1116     bool retval=true;
1117
1118     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1119         it != m_IsoHandlers.end();
1120         ++it )
1121     {
1122         debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handler (%p)\n",*it);
1123
1124         if(!(*it)->requestDisable()) {
1125             debugOutput( DEBUG_LEVEL_VERBOSE, " could not request disable for handler %p\n",*it);
1126             return false;
1127         }
1128
1129         if((*it)->getType() == IsoHandler::eHT_Transmit) {
1130             m_IsoTaskTransmit->requestShadowMapUpdate();
1131         } else {
1132             m_IsoTaskReceive->requestShadowMapUpdate();
1133         }
1134
1135         debugOutput(DEBUG_LEVEL_VERBOSE, " requested disable for handler %p\n", *it);
1136     }
1137
1138     if (retval) {
1139         m_State=E_Prepared;
1140     } else {
1141         m_State=E_Error;
1142     }
1143     return retval;
1144 }
1145
1146 bool IsoHandlerManager::reset() {
1147     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
1148     // check state
1149     if(m_State == E_Error) {
1150         debugFatal("Resetting from error condition not yet supported...\n");
1151         return false;
1152     }
1153     // if not in an error condition, reset means stop the handlers
1154     return stopHandlers();
1155 }
1156
1157 void IsoHandlerManager::setVerboseLevel(int i) {
1158     setDebugLevel(i);
1159     // propagate the debug level
1160     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1161           it != m_IsoHandlers.end();
1162           ++it )
1163     {
1164         (*it)->setVerboseLevel(i);
1165     }
1166     if(m_IsoThreadTransmit) m_IsoThreadTransmit->setVerboseLevel(i);
1167     if(m_IsoTaskTransmit)   m_IsoTaskTransmit->setVerboseLevel(i);
1168     if(m_IsoThreadReceive)  m_IsoThreadReceive->setVerboseLevel(i);
1169     if(m_IsoTaskReceive)    m_IsoTaskReceive->setVerboseLevel(i);
1170     setDebugLevel(i);
1171     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i );
1172 }
1173
1174 void IsoHandlerManager::dumpInfo() {
1175     #ifdef DEBUG
1176     unsigned int i=0;
1177     debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping IsoHandlerManager Stream handler information...\n");
1178     debugOutputShort( DEBUG_LEVEL_NORMAL, " State: %d\n",(int)m_State);
1179
1180     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1181           it != m_IsoHandlers.end();
1182           ++it )
1183     {
1184         debugOutputShort( DEBUG_LEVEL_NORMAL, " IsoHandler %d (%p)\n",i++,*it);
1185         (*it)->dumpInfo();
1186     }
1187     #endif
1188 }
1189
1190 const char *
1191 IsoHandlerManager::eHSToString(enum eHandlerStates s) {
1192     switch (s) {
1193         default: return "Invalid";
1194         case E_Created: return "Created";
1195         case E_Prepared: return "Prepared";
1196         case E_Running: return "Running";
1197         case E_Error: return "Error";
1198     }
1199 }
1200
1201
1202 // ISOHANDLER
1203
1204 /* the C callbacks */
1205 enum raw1394_iso_disposition
1206 IsoHandlerManager::IsoHandler::iso_transmit_handler(raw1394handle_t handle,
1207         unsigned char *data, unsigned int *length,
1208         unsigned char *tag, unsigned char *sy,
1209         int cycle, unsigned int dropped1) {
1210
1211     IsoHandler *xmitHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle));
1212     assert(xmitHandler);
1213     unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16;
1214     unsigned int dropped = dropped1 & 0xFFFF;
1215     return xmitHandler->getPacket(data, length, tag, sy, cycle, dropped, skipped);
1216 }
1217
1218 enum raw1394_iso_disposition
1219 IsoHandlerManager::IsoHandler::iso_receive_handler(raw1394handle_t handle, unsigned char *data,
1220                         unsigned int length, unsigned char channel,
1221                         unsigned char tag, unsigned char sy, unsigned int cycle,
1222                         unsigned int dropped) {
1223
1224     IsoHandler *recvHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle));
1225     assert(recvHandler);
1226
1227     return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped);
1228 }
1229
1230 IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t)
1231    : m_manager( manager )
1232    , m_type ( t )
1233    , m_handle( NULL )
1234    , m_buf_packets( 400 )
1235    , m_max_packet_size( 1024 )
1236    , m_irq_interval( -1 )
1237    , m_last_cycle( -1 )
1238    , m_last_now( 0xFFFFFFFF )
1239    , m_last_packet_handled_at( 0xFFFFFFFF )
1240    , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER )
1241    , m_Client( 0 )
1242    , m_speed( RAW1394_ISO_SPEED_400 )
1243    , m_State( eHS_Stopped )
1244    , m_NextState( eHS_Stopped )
1245    , m_switch_on_cycle(0)
1246 #ifdef DEBUG
1247    , m_packets ( 0 )
1248    , m_dropped( 0 )
1249    , m_skipped( 0 )
1250    , m_min_ahead( 7999 )
1251 #endif
1252 {
1253     pthread_mutex_init(&m_disable_lock, NULL);
1254 }
1255
1256 IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t,
1257                        unsigned int buf_packets, unsigned int max_packet_size, int irq)
1258    : m_manager( manager )
1259    , m_type ( t )
1260    , m_handle( NULL )
1261    , m_buf_packets( buf_packets )
1262    , m_max_packet_size( max_packet_size )
1263    , m_irq_interval( irq )
1264    , m_last_cycle( -1 )
1265    , m_last_now( 0xFFFFFFFF )
1266    , m_last_packet_handled_at( 0xFFFFFFFF )
1267    , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER )
1268    , m_Client( 0 )
1269    , m_speed( RAW1394_ISO_SPEED_400 )
1270    , m_State( eHS_Stopped )
1271    , m_NextState( eHS_Stopped )
1272    , m_switch_on_cycle(0)
1273 #ifdef DEBUG
1274    , m_packets ( 0 )
1275    , m_dropped( 0 )
1276    , m_skipped( 0 )
1277    , m_min_ahead( 7999 )
1278 #endif
1279 {
1280     pthread_mutex_init(&m_disable_lock, NULL);
1281 }
1282
1283 IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t, unsigned int buf_packets,
1284                        unsigned int max_packet_size, int irq,
1285                        enum raw1394_iso_speed speed)
1286    : m_manager( manager )
1287    , m_type ( t )
1288    , m_handle( NULL )
1289    , m_buf_packets( buf_packets )
1290    , m_max_packet_size( max_packet_size )
1291    , m_irq_interval( irq )
1292    , m_last_cycle( -1 )
1293    , m_last_now( 0xFFFFFFFF )
1294    , m_last_packet_handled_at( 0xFFFFFFFF )
1295    , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER )
1296    , m_Client( 0 )
1297    , m_speed( speed )
1298    , m_State( eHS_Stopped )
1299    , m_NextState( eHS_Stopped )
1300    , m_switch_on_cycle(0)
1301 #ifdef DEBUG
1302    , m_packets( 0 )
1303    , m_dropped( 0 )
1304    , m_skipped( 0 )
1305    , m_min_ahead( 7999 )
1306 #endif
1307 {
1308     pthread_mutex_init(&m_disable_lock, NULL);
1309 }
1310
1311 IsoHandlerManager::IsoHandler::~IsoHandler() {
1312 // Don't call until libraw1394's raw1394_new_handle() function has been
1313 // fixed to correctly initialise the iso_packet_infos field.  Bug is
1314 // confirmed present in libraw1394 1.2.1.  In any case,
1315 // raw1394_destroy_handle() will do any iso system shutdown required.
1316 //     raw1394_iso_shutdown(m_handle);
1317
1318 // Typically, by the time this function is called the IsoTask thread would
1319 // have called disable() on the handler (in the FW_ISORCV/FW_ISOXMT
1320 // threads).  However, the raw1394_destroy_handle() call therein takes
1321 // upwards of 20 milliseconds to complete under the new kernel firewire
1322 // stack, and may not have completed by the time ~IsoHandler() is called by
1323 // the "jackd" thread.  Thus, wait for the lock before testing the state
1324 // of the handle so any in-progress disable() is complete.
1325     if (pthread_mutex_trylock(&m_disable_lock) == EBUSY) {
1326         pthread_mutex_lock(&m_disable_lock);
1327         pthread_mutex_unlock(&m_disable_lock);
1328     }
1329     if(m_handle) {
1330         if (m_State == eHS_Running) {
1331             debugError("BUG: Handler still running!\n");
1332             disable();
1333         }
1334     }
1335     pthread_mutex_destroy(&m_disable_lock);
1336 }
1337
1338 bool
1339 IsoHandlerManager::IsoHandler::canIterateClient()
1340 {
1341     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "checking...\n");
1342     if(m_Client) {
1343         bool result;
1344
1345         if (m_type == eHT_Receive) {
1346             result = m_Client->canProducePacket();
1347         } else {
1348             result = m_Client->canConsumePacket();
1349         }
1350         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result);
1351         return result && (m_State != eHS_Error);
1352     } else {
1353         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " no client\n");
1354     }
1355     return false;
1356 }
1357
1358 bool
1359 IsoHandlerManager::IsoHandler::iterate() {
1360     return iterate(m_manager.get1394Service().getCycleTimer());
1361 }
1362
1363 bool
1364 IsoHandlerManager::IsoHandler::iterate(uint32_t cycle_timer_now) {
1365     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) Iterating ISO handler at %08X...\n",
1366                        this, getTypeString(), cycle_timer_now);
1367     m_last_now = cycle_timer_now;
1368     if(m_State == eHS_Running) {
1369         assert(m_handle);
1370
1371         #if ISOHANDLER_FLUSH_BEFORE_ITERATE
1372         // this flushes all packets received since the poll() returned
1373         // from kernel to userspace such that they are processed by this
1374         // iterate. Doing so might result in lower latency capability
1375         // and/or better reliability
1376         if(m_type == eHT_Receive) {
1377             raw1394_iso_recv_flush(m_handle);
1378         }
1379         #endif
1380
1381         if(raw1394_loop_iterate(m_handle)) {
1382             debugError( "IsoHandler (%p): Failed to iterate handler: %s\n",
1383                         this, strerror(errno));
1384             return false;
1385         }
1386         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) done interating ISO handler...\n",
1387                            this, getTypeString());
1388         return true;
1389     } else {
1390         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) Not iterating a non-running handler...\n",
1391                     this, getTypeString());
1392         return false;
1393     }
1394 }
1395
1396 /**
1397  * Bus reset handler
1398  *
1399  * @return ?
1400  */
1401
1402 bool
1403 IsoHandlerManager::IsoHandler::handleBusReset()
1404 {
1405     debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n");
1406     m_last_packet_handled_at = 0xFFFFFFFF;
1407
1408     #define CSR_CYCLE_TIME            0x200
1409     #define CSR_REGISTER_BASE  0xfffff0000000ULL
1410     // do a simple read on ourself in order to update the internal structures
1411     // this avoids read failures after a bus reset
1412     quadlet_t buf=0;
1413     raw1394_read(m_handle, raw1394_get_local_id(m_handle),
1414                  CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf);
1415
1416     return m_Client->handleBusReset();
1417 }
1418
1419 /**
1420  * Call this if you find out that this handler has died for some
1421  * external reason.
1422  */
1423 void
1424 IsoHandlerManager::IsoHandler::notifyOfDeath()
1425 {
1426     m_State = eHS_Error;
1427     m_NextState = eHS_Error;
1428
1429     // notify the client of the fact that we have died
1430     m_Client->handlerDied();
1431
1432     // wake ourselves up
1433     if(m_handle) raw1394_wake_up(m_handle);
1434 }
1435
1436 void IsoHandlerManager::IsoHandler::dumpInfo()
1437 {
1438     int channel=-1;
1439     if (m_Client) channel=m_Client->getChannel();
1440
1441     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Handler type................: %s\n",
1442             getTypeString());
1443     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel...............: %2d, %2d\n",
1444             m_manager.get1394Service().getPort(), channel);
1445     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer, MaxPacketSize, IRQ..: %4d, %4d, %4d\n",
1446             m_buf_packets, m_max_packet_size, m_irq_interval);
1447     if (this->getType() == eHT_Transmit) {
1448         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Speed ..................: %2d\n",
1449                                             m_speed);
1450         #ifdef DEBUG
1451         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Min ISOXMT bufferfill : %04d\n", m_min_ahead);
1452         #endif
1453     }
1454     #ifdef DEBUG
1455     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Last cycle, dropped.........: %4d, %4u, %4u\n",
1456             m_last_cycle, m_dropped, m_skipped);
1457     #endif
1458
1459 }
1460
1461 void IsoHandlerManager::IsoHandler::setVerboseLevel(int l)
1462 {
1463     setDebugLevel(l);
1464     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
1465 }
1466
1467 bool IsoHandlerManager::IsoHandler::registerStream(StreamProcessor *stream)
1468 {
1469     assert(stream);
1470     debugOutput( DEBUG_LEVEL_VERBOSE, "registering stream (%p)\n", stream);
1471
1472     if (m_Client) {
1473             debugFatal( "Generic IsoHandlers can have only one client\n");
1474             return false;
1475     }
1476     m_Client=stream;
1477     return true;
1478 }
1479
1480 bool IsoHandlerManager::IsoHandler::unregisterStream(StreamProcessor *stream)
1481 {
1482     assert(stream);
1483     debugOutput( DEBUG_LEVEL_VERBOSE, "unregistering stream (%p)\n", stream);
1484
1485     if(stream != m_Client) {
1486             debugFatal( "no client registered\n");
1487             return false;
1488     }
1489     m_Client=0;
1490     return true;
1491 }
1492
1493 // ISO packet interface
1494 enum raw1394_iso_disposition IsoHandlerManager::IsoHandler::putPacket(
1495                     unsigned char *data, unsigned int length,
1496                     unsigned char channel, unsigned char tag, unsigned char sy,
1497                     unsigned int cycle, unsigned int dropped) {
1498     // keep track of dropped cycles
1499     int dropped_cycles = 0;
1500     if (m_last_cycle != (int)cycle && m_last_cycle != -1 && m_manager.m_MissedCyclesOK == false) {
1501         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
1502         #ifdef DEBUG
1503         if (dropped_cycles < 0) {
1504             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d\n",
1505                          this, dropped_cycles, cycle, m_last_cycle, dropped);
1506         }
1507         if (dropped_cycles > 0) {
1508             debugOutput(DEBUG_LEVEL_VERBOSE,
1509                         "(%p) dropped %d packets on cycle %u, 'dropped'=%u, cycle=%d, m_last_cycle=%d\n",
1510                         this, dropped_cycles, cycle, dropped, cycle, m_last_cycle);
1511             m_dropped += dropped_cycles;
1512         }
1513         #endif
1514     }
1515     m_last_cycle = cycle;
1516
1517     // the m_last_now value is set when the iterate() function is called.
1518     uint32_t now_cycles = CYCLE_TIMER_GET_CYCLES(m_last_now);
1519
1520     // two cases can occur:
1521     // (1) this packet has been received before iterate() was called (normal case).
1522     // (2) this packet has been received after iterate() was called.
1523     //     happens when the kernel flushes more packets while we are already processing.
1524     //
1525     // In case (1) now_cycles is a small number of cycles larger than cycle. In
1526     // case (2) now_cycles is a small number of cycles smaller than cycle.
1527     // hence  abs(diffCycles(now_cycles, cycles)) has to be 'small'
1528
1529     // we can calculate the time of arrival for this packet as
1530     // 'now' + diffCycles(cycles, now_cycles) * TICKS_PER_CYCLE
1531     // in its properly wrapped version
1532     int64_t diff_cycles = diffCycles(cycle, now_cycles);
1533     int64_t tmp = CYCLE_TIMER_TO_TICKS(m_last_now);
1534     tmp += diff_cycles * (int64_t)TICKS_PER_CYCLE;
1535     uint64_t pkt_ctr_ticks = wrapAtMinMaxTicks(tmp);
1536     uint32_t pkt_ctr = TICKS_TO_CYCLE_TIMER(pkt_ctr_ticks);
1537     #ifdef DEBUG
1538     if( (now_cycles < cycle)
1539         && diffCycles(now_cycles, cycle) < 0
1540         // ignore this on dropped cycles, since it's normal
1541         // that now is ahead on the received packets (as we miss packets)
1542         && dropped_cycles == 0)
1543     {
1544         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Special non-unwrapping happened\n");
1545     }
1546     #endif
1547
1548     #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION
1549     // add a seconds field
1550     uint32_t now = m_manager.get1394Service().getCycleTimer();
1551     uint32_t now_secs_ref = CYCLE_TIMER_GET_SECS(now);
1552     // causality results in the fact that 'now' is always after 'cycle'
1553     // or at best, equal (if this handler was called within 125us after
1554     // the packet was on the wire).
1555     if(CYCLE_TIMER_GET_CYCLES(now) < cycle) {
1556         // the cycle field has wrapped, substract one second
1557         if(now_secs_ref == 0) {
1558             now_secs_ref = 127;
1559         } else  {
1560             now_secs_ref -= 1;
1561         }
1562     }
1563     uint32_t pkt_ctr_ref = cycle << 12;
1564     pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25;
1565
1566     if((pkt_ctr & ~0x0FFFL) != pkt_ctr_ref) {
1567         debugWarning("reconstructed CTR counter discrepancy\n");
1568         debugWarning(" ingredients: %X, %X, %X, %X, %X, %d, %ld, %ld, %"PRId64"\n",
1569                      cycle, pkt_ctr_ref, pkt_ctr,
1570                      now, m_last_now, now_secs_ref,
1571                      (long int)CYCLE_TIMER_GET_SECS(now),
1572                      (long int)CYCLE_TIMER_GET_SECS(m_last_now),
1573                      tmp);
1574         debugWarning(" diffcy = %"PRId64" \n", diff_cycles);
1575     }
1576     #endif
1577     m_last_packet_handled_at = pkt_ctr;
1578
1579     // leave the offset field (for now?)
1580
1581     debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE,
1582                 "received packet: length=%d, channel=%d, cycle=%d, at %08X\n",
1583                 length, channel, cycle, pkt_ctr);
1584     m_packets++;
1585     #ifdef DEBUG
1586     if (length > m_max_packet_size) {
1587         debugWarning("(%p, %s) packet too large: len=%u max=%u\n",
1588                      this, getTypeString(), length, m_max_packet_size);
1589     }
1590     if(m_last_cycle == -1) {
1591         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %u)\n", getTypeString(), this, cycle);
1592     }
1593     #endif
1594
1595     // iterate the client if required
1596     if(m_Client)
1597         return m_Client->putPacket(data, length, channel, tag, sy, pkt_ctr, dropped_cycles);
1598
1599     return RAW1394_ISO_OK;
1600 }
1601
1602 enum raw1394_iso_disposition
1603 IsoHandlerManager::IsoHandler::getPacket(unsigned char *data, unsigned int *length,
1604                       unsigned char *tag, unsigned char *sy,
1605                       int cycle, unsigned int dropped, unsigned int skipped) {
1606
1607     uint32_t pkt_ctr;
1608     if (cycle < 0) {
1609         // mark invalid
1610         pkt_ctr = 0xFFFFFFFF;
1611     } else {
1612         // the m_last_now value is set when the iterate() function is called.
1613         uint32_t now_cycles = CYCLE_TIMER_GET_CYCLES(m_last_now);
1614
1615         // two cases can occur:
1616         // (1) this packet has been received before iterate() was called (normal case).
1617         // (2) this packet has been received after iterate() was called.
1618         //     happens when the kernel flushes more packets while we are already processing.
1619         //
1620         // In case (1) now_cycles is a small number of cycles larger than cycle. In
1621         // case (2) now_cycles is a small number of cycles smaller than cycle.
1622         // hence  abs(diffCycles(now_cycles, cycles)) has to be 'small'
1623
1624         // we can calculate the time of arrival for this packet as
1625         // 'now' + diffCycles(cycles, now_cycles) * TICKS_PER_CYCLE
1626         // in its properly wrapped version
1627         int64_t diff_cycles = diffCycles(cycle, now_cycles);
1628         int64_t tmp = CYCLE_TIMER_TO_TICKS(m_last_now);
1629         tmp += diff_cycles * (int64_t)TICKS_PER_CYCLE;
1630         uint64_t pkt_ctr_ticks = wrapAtMinMaxTicks(tmp);
1631         pkt_ctr = TICKS_TO_CYCLE_TIMER(pkt_ctr_ticks);
1632
1633         #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION
1634         // add a seconds field
1635         uint32_t now = m_manager.get1394Service().getCycleTimer();
1636         uint32_t now_secs_ref = CYCLE_TIMER_GET_SECS(now);
1637         // causality results in the fact that 'now' is always after 'cycle'
1638         if(CYCLE_TIMER_GET_CYCLES(now) > (unsigned int)cycle) {
1639             // the cycle field has wrapped, add one second
1640             now_secs_ref += 1;
1641             // no need for this:
1642             if(now_secs_ref == 128) {
1643                now_secs_ref = 0;
1644             }
1645         }
1646         uint32_t pkt_ctr_ref = cycle << 12;
1647         pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25;
1648
1649         if(((pkt_ctr & ~0x0FFFL) != pkt_ctr_ref) && (m_packets > m_buf_packets)) {
1650             debugWarning("reconstructed CTR counter discrepancy\n");
1651             debugWarning(" ingredients: %X, %X, %X, %X, %X, %d, %ld, %ld, %"PRId64"\n",
1652                         cycle, pkt_ctr_ref, pkt_ctr,
1653                          now, m_last_now, now_secs_ref,
1654                          (long int)CYCLE_TIMER_GET_SECS(now),
1655                          (long int)CYCLE_TIMER_GET_SECS(m_last_now),
1656                          tmp);
1657             debugWarning(" diffcy = %"PRId64" \n", diff_cycles);
1658         }
1659         #endif
1660     }
1661     if (m_packets < m_buf_packets) { // these are still prebuffer packets
1662         m_last_packet_handled_at = 0xFFFFFFFF;
1663     } else {
1664         m_last_packet_handled_at = pkt_ctr;
1665     }
1666     debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE,
1667                 "sending packet: length=%d, cycle=%d, at %08X\n",
1668                 *length, cycle, pkt_ctr);
1669
1670     m_packets++;
1671
1672     #ifdef DEBUG
1673     if(m_last_cycle == -1) {
1674         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive. cycle=%d state=%i\n", getTypeString(), this, cycle, m_State);
1675     }
1676     #endif
1677
1678     // keep track of dropped cycles
1679     int dropped_cycles = 0;
1680     if (m_last_cycle != cycle && m_last_cycle != -1) {
1681         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
1682         // correct for skipped packets
1683         // since those are not dropped, but only delayed
1684         dropped_cycles -= skipped;
1685
1686         #ifdef DEBUG
1687         if(skipped) {
1688             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
1689                         "(%p) skipped %d cycles, cycle: %d, last_cycle: %d, dropped: %d\n",
1690                         this, skipped, cycle, m_last_cycle, dropped);
1691             m_skipped += skipped;
1692         }
1693         if (dropped_cycles < 0) {
1694             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d, skipped: %d\n",
1695                          this, dropped_cycles, cycle, m_last_cycle, dropped, skipped);
1696         }
1697         if (dropped_cycles > 0) {
1698             debugOutput(DEBUG_LEVEL_VERBOSE,
1699                         "(%p) dropped %d packets on cycle %u (last_cycle=%u, dropped=%d, skipped: %d)\n",
1700                         this, dropped_cycles, cycle, m_last_cycle, dropped, skipped);
1701             m_dropped += dropped_cycles - skipped;
1702         }
1703         #endif
1704     }
1705     if (cycle >= 0) {
1706         m_last_cycle = cycle;
1707        
1708         #ifdef DEBUG
1709 /*        int ahead = diffCycles(cycle, now_cycles);
1710         if (ahead < m_min_ahead) m_min_ahead = ahead;
1711 */
1712         #endif
1713     }
1714
1715     #ifdef DEBUG
1716     if (dropped > 0) {
1717         debugOutput(DEBUG_LEVEL_VERBOSE,
1718                     "(%p) OHCI issue on cycle %u (dropped_cycles=%d, last_cycle=%u, dropped=%d, skipped: %d)\n",
1719                     this, cycle, dropped_cycles, m_last_cycle, dropped, skipped);
1720     }
1721     #endif
1722
1723     if(m_Client) {
1724         enum raw1394_iso_disposition retval;
1725         retval = m_Client->getPacket(data, length, tag, sy, pkt_ctr, dropped_cycles, skipped, m_max_packet_size);
1726         #ifdef DEBUG
1727         if (*length > m_max_packet_size) {
1728             debugWarning("(%p, %s) packet too large: len=%u max=%u\n",
1729                          this, getTypeString(), *length, m_max_packet_size);
1730         }
1731         #endif
1732             return retval;
1733     }
1734
1735     *tag = 0;
1736     *sy = 0;
1737     *length = 0;
1738     return RAW1394_ISO_OK;
1739 }
1740
1741 bool
1742 IsoHandlerManager::IsoHandler::enable(int cycle)
1743 {
1744     debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d\n", cycle);
1745
1746     // check the state
1747     if(m_State != eHS_Stopped) {
1748         debugError("Incorrect state, expected eHS_Stopped, got %d\n",(int)m_State);
1749         return false;
1750     }
1751
1752     assert(m_handle == NULL);
1753
1754     // create a handle for the ISO traffic
1755     m_handle = raw1394_new_handle_on_port( m_manager.get1394Service().getPort() );
1756     if ( !m_handle ) {
1757         if ( !errno ) {
1758             debugError("libraw1394 not compatible\n");
1759         } else {
1760             debugError("Could not get 1394 handle: %s\n", strerror(errno) );
1761             debugError("Are ieee1394 and raw1394 drivers loaded?\n");
1762         }
1763         return false;
1764     }
1765     raw1394_set_userdata(m_handle, static_cast<void *>(this));
1766
1767     // prepare the handler, allocate the resources
1768     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso handler (%p, client=%p)\n", this, m_Client);
1769     dumpInfo();
1770     if (getType() == eHT_Receive) {
1771         if(raw1394_iso_recv_init(m_handle,
1772                                 iso_receive_handler,
1773                                 m_buf_packets,
1774                                 m_max_packet_size,
1775                                 m_Client->getChannel(),
1776                                 m_receive_mode,
1777                                 m_irq_interval)) {
1778             debugFatal("Could not do receive initialization (PACKET_PER_BUFFER)!\n" );
1779             debugFatal("  %s\n",strerror(errno));
1780             return false;
1781         }
1782
1783         if(raw1394_iso_recv_start(m_handle, cycle, -1, 0)) {
1784             debugFatal("Could not start receive handler (%s)\n",strerror(errno));
1785             dumpInfo();
1786             return false;
1787         }
1788     } else {
1789         if(raw1394_iso_xmit_init(m_handle,
1790                                 iso_transmit_handler,
1791                                 m_buf_packets,
1792                                 m_max_packet_size,
1793                                 m_Client->getChannel(),
1794                                 m_speed,
1795                                 m_irq_interval)) {
1796             debugFatal("Could not do xmit initialisation!\n" );
1797             return false;
1798         }
1799
1800         if(raw1394_iso_xmit_start(m_handle, cycle, 0)) {
1801             debugFatal("Could not start xmit handler (%s)\n", strerror(errno));
1802             dumpInfo();
1803             return false;
1804         }
1805     }
1806
1807 #ifdef DEBUG
1808     m_min_ahead = 7999;
1809 #endif
1810
1811     m_packets = 0;
1812
1813     // indicate that the first iterate() still has to occur.
1814     m_last_now = 0xFFFFFFFF;
1815     m_last_packet_handled_at = 0xFFFFFFFF;
1816
1817     m_State = eHS_Running;
1818     m_NextState = eHS_Running;
1819     return true;
1820 }
1821
1822 bool
1823 IsoHandlerManager::IsoHandler::disable()
1824 {
1825     signed int i, have_lock = 0;
1826
1827     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) enter...\n",
1828                  this, (m_type==eHT_Receive?"Receive":"Transmit"));
1829
1830     i = pthread_mutex_trylock(&m_disable_lock);
1831     if (i == 0)
1832         have_lock = 1;
1833     else
1834     if (i == EBUSY) {
1835         // Some other thread is disabling this handler, a process which can
1836         // take considerable time when using the new kernel firewire stack.
1837         // Wait until it is finished before returning so the present caller
1838         // can act knowing that the disable has occurred and is complete
1839         // (which is what normally would be expected).
1840         debugOutput( DEBUG_LEVEL_VERBOSE, "waiting for disable lock\n");
1841         pthread_mutex_lock(&m_disable_lock);
1842         debugOutput( DEBUG_LEVEL_VERBOSE, "now have disable lock\n");
1843         if (m_State == eHS_Stopped) {
1844             debugOutput( DEBUG_LEVEL_VERBOSE, "another disable() has completed\n");
1845             pthread_mutex_unlock(&m_disable_lock);
1846             return true;
1847         }
1848         have_lock = 1;
1849     }
1850
1851     // check state
1852     if(m_State != eHS_Running) {
1853         debugError("Incorrect state, expected eHS_Running, got %d\n",(int)m_State);
1854         if (have_lock)
1855             pthread_mutex_unlock(&m_disable_lock);
1856         return false;
1857     }
1858
1859     assert(m_handle != NULL);
1860
1861     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) wake up handle...\n",
1862                  this, (m_type==eHT_Receive?"Receive":"Transmit"));
1863
1864     // wake up any waiting reads/polls
1865     raw1394_wake_up(m_handle);
1866
1867     // this is put here to try and avoid the
1868     // Runaway context problem
1869     // don't know if it will help though.
1870 /*    if(m_State != eHS_Error) { // if the handler is dead, this might block forever
1871         raw1394_iso_xmit_sync(m_handle);
1872     }*/
1873     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) stop...\n",
1874                  this, (m_type==eHT_Receive?"Receive":"Transmit"));
1875
1876     // stop iso traffic
1877     raw1394_iso_stop(m_handle);
1878     // deallocate resources
1879
1880     // Don't call until libraw1394's raw1394_new_handle() function has been
1881     // fixed to correctly initialise the iso_packet_infos field.  Bug is
1882     // confirmed present in libraw1394 1.2.1.
1883     raw1394_iso_shutdown(m_handle);
1884
1885     // When running on the new kernel firewire stack, this call can take of
1886     // the order of 20 milliseconds to return, in which time other threads
1887     // may wish to test the state of the handler and call this function
1888     // themselves.  The m_disable_lock mutex is used to work around this.
1889     raw1394_destroy_handle(m_handle);
1890     m_handle = NULL;
1891
1892     m_State = eHS_Stopped;
1893     m_NextState = eHS_Stopped;
1894
1895     if (have_lock)
1896         pthread_mutex_unlock(&m_disable_lock);
1897     return true;
1898 }
1899
1900 // functions to request enable or disable at the next opportunity
1901 bool
1902 IsoHandlerManager::IsoHandler::requestEnable(int cycle)
1903 {
1904     if (m_State == eHS_Running) {
1905         debugError("Enable requested on enabled stream '%s'\n", getTypeString());
1906         return false;
1907     }
1908     if (m_State != eHS_Stopped) {
1909         debugError("Enable requested on stream '%s' with state: %d\n", getTypeString(), m_State);
1910         return false;
1911     }
1912     m_NextState = eHS_Running;
1913     return true;
1914 }
1915
1916 bool
1917 IsoHandlerManager::IsoHandler::requestDisable()
1918 {
1919     if (m_State == eHS_Stopped) {
1920         // Don't treat this as an error condition because during a user
1921         // shutdown the stream would have been disabled by
1922         // stopHandlerForStream().  Therefore when requestDisable() is
1923         // subnsequently called by IsoHandlerManager::stopHandlers() in the
1924         // IsoHandlerManager destructor with the stream disabled the
1925         // condition is not an error.
1926         //
1927         // For now print a warning, but this might be removed in future if
1928         // the above framework remains in place.
1929         debugWarning("Disable requested on disabled stream\n");
1930         return true;
1931     }
1932     if (m_State != eHS_Running) {
1933         debugError("Disable requested on stream with state=%d\n", m_State);
1934         return false;
1935     }
1936     m_NextState = eHS_Stopped;
1937     return true;
1938 }
1939
1940 // Explicitly preset m_switch_on_cycle since requestEnable doesn't do this
1941 // and thus all enables requested via that route always occur on cycle 0.
1942 void
1943 IsoHandlerManager::IsoHandler::setIsoStartCycle(signed int cycle)
1944 {
1945   m_switch_on_cycle = cycle;
1946 }
1947
1948 void
1949 IsoHandlerManager::IsoHandler::updateState()
1950 {
1951     // execute state changes requested
1952     if(m_State != m_NextState) {
1953         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) handler needs state update from %d => %d\n", this, m_State, m_NextState);
1954         if(m_State == eHS_Stopped && m_NextState == eHS_Running) {
1955             debugOutput(DEBUG_LEVEL_VERBOSE, "handler has to be enabled\n");
1956             enable(m_switch_on_cycle);
1957         } else if(m_State == eHS_Running && m_NextState == eHS_Stopped) {
1958             debugOutput(DEBUG_LEVEL_VERBOSE, "handler has to be disabled\n");
1959             disable();
1960         } else {
1961             debugError("Unknown state transition\n");
1962         }
1963     }
1964 }
1965
1966 /**
1967  * @brief convert a EHandlerType to a string
1968  * @param t the type
1969  * @return a char * describing the state
1970  */
1971 const char *
1972 IsoHandlerManager::IsoHandler::eHTToString(enum EHandlerType t) {
1973     switch (t) {
1974         case eHT_Receive: return "Receive";
1975         case eHT_Transmit: return "Transmit";
1976         default: return "error: unknown type";
1977     }
1978 }
Note: See TracBrowser for help on using the browser.