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

Revision 2811, 72.1 kB (checked in by jwoithe, 3 years ago)

Cosmetic: "firewire" should be "FireWire?" when used as the bus name.

Similarly to r2802 and r2810, "FireWire?" should be used when referring to
the name of the bus. This patch corrects this throughout the source tree
for completeness. While there are a small number of mostly debug output
strings affected, most of the changes are to comments or developer documents
where they are of little consequence. Thanks to Pander who suggested the
need to look into this on the ffado-devel mailing list.

At least in theory, remaining instances of "firewire" in the source tree
should remain as they are because they refer to case-sensitive identifiers
defined externally (such as the "firewire" jackd backend name).

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.