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

Revision 2651, 72.1 kB (checked in by jwoithe, 4 years ago)

Fix some warnings emitted by recent versions of gcc. These are mostly connected with printf format strings: spaces are now required between string literals and PR* format macros. Patch from Xavier Forestier.

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