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

Revision 1046, 22.4 kB (checked in by ppalmers, 16 years ago)

debug message cleanup. move #defines into config.h.in.

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 "IsoHandler.h"
27 #include "ieee1394service.h"
28 #include "IsoHandlerManager.h"
29
30 #include "cycletimer.h"
31
32 #include "libstreaming/generic/StreamProcessor.h"
33 #include "libutil/PosixThread.h"
34
35 #include <errno.h>
36 #include <netinet/in.h>
37 #include <assert.h>
38 #include <unistd.h>
39 #include <string.h>
40
41 #include <iostream>
42 using namespace std;
43 using namespace Streaming;
44
45 IMPL_DEBUG_MODULE( IsoHandler, IsoHandler, DEBUG_LEVEL_NORMAL );
46
47 /* the C callbacks */
48 enum raw1394_iso_disposition
49 IsoHandler::iso_transmit_handler(raw1394handle_t handle,
50         unsigned char *data, unsigned int *length,
51         unsigned char *tag, unsigned char *sy,
52         int cycle, unsigned int dropped1) {
53
54     IsoHandler *xmitHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle));
55     assert(xmitHandler);
56     unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16;
57     unsigned int dropped = dropped1 & 0xFFFF;
58     return xmitHandler->getPacket(data, length, tag, sy, cycle, dropped, skipped);
59 }
60
61 enum raw1394_iso_disposition
62 IsoHandler::iso_receive_handler(raw1394handle_t handle, unsigned char *data,
63                         unsigned int length, unsigned char channel,
64                         unsigned char tag, unsigned char sy, unsigned int cycle,
65                         unsigned int dropped1) {
66
67     IsoHandler *recvHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle));
68     assert(recvHandler);
69
70     unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16;
71     unsigned int dropped = dropped1 & 0xFFFF;
72
73     return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped, skipped);
74 }
75
76 int IsoHandler::busreset_handler(raw1394handle_t handle, unsigned int generation)
77 {
78     debugOutput( DEBUG_LEVEL_VERBOSE, "Busreset happened, generation %d...\n", generation);
79
80     IsoHandler *handler = static_cast<IsoHandler *>(raw1394_get_userdata(handle));
81     assert(handler);
82     return handler->handleBusReset(generation);
83 }
84
85 IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t)
86    : m_manager( manager )
87    , m_type ( t )
88    , m_handle( 0 )
89    , m_buf_packets( 400 )
90    , m_max_packet_size( 1024 )
91    , m_irq_interval( -1 )
92    , m_last_cycle( -1 )
93    , m_last_now( 0xFFFFFFFF )
94    , m_Client( 0 )
95    , m_speed( RAW1394_ISO_SPEED_400 )
96    , m_prebuffers( 0 )
97    , m_dont_exit_iterate_loop( true )
98    , m_State( E_Created )
99 #ifdef DEBUG
100    , m_packets ( 0 )
101    , m_dropped( 0 )
102    , m_min_ahead( 7999 )
103 #endif
104 {
105 }
106
107 IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t,
108                        unsigned int buf_packets, unsigned int max_packet_size, int irq)
109    : m_manager( manager )
110    , m_type ( t )
111    , m_handle( 0 )
112    , m_buf_packets( buf_packets )
113    , m_max_packet_size( max_packet_size )
114    , m_irq_interval( irq )
115    , m_last_cycle( -1 )
116    , m_last_now( 0xFFFFFFFF )
117    , m_Client( 0 )
118    , m_speed( RAW1394_ISO_SPEED_400 )
119    , m_prebuffers( 0 )
120    , m_State( E_Created )
121 #ifdef DEBUG
122    , m_packets ( 0 )
123    , m_dropped( 0 )
124    , m_min_ahead( 7999 )
125 #endif
126 {
127 }
128
129 IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t, unsigned int buf_packets,
130                        unsigned int max_packet_size, int irq,
131                        enum raw1394_iso_speed speed)
132    : m_manager( manager )
133    , m_type ( t )
134    , m_handle( 0 )
135    , m_buf_packets( buf_packets )
136    , m_max_packet_size( max_packet_size )
137    , m_irq_interval( irq )
138    , m_last_cycle( -1 )
139    , m_last_now( 0xFFFFFFFF )
140    , m_Client( 0 )
141    , m_speed( speed )
142    , m_prebuffers( 0 )
143    , m_State( E_Created )
144 #ifdef DEBUG
145    , m_packets( 0 )
146    , m_dropped( 0 )
147 #endif
148 {
149 }
150
151 IsoHandler::~IsoHandler() {
152 // Don't call until libraw1394's raw1394_new_handle() function has been
153 // fixed to correctly initialise the iso_packet_infos field.  Bug is
154 // confirmed present in libraw1394 1.2.1.  In any case,
155 // raw1394_destroy_handle() will do any iso system shutdown required.
156 //     raw1394_iso_shutdown(m_handle);
157     if(m_handle) {
158         if (m_State == E_Running) {
159             disable();
160         }
161         raw1394_destroy_handle(m_handle);
162     }
163 }
164
165 bool
166 IsoHandler::canIterateClient()
167 {
168     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "checking...\n");
169     if(m_Client) {
170         bool result;
171         if (m_type == eHT_Receive) {
172             result = m_Client->canProducePacket();
173         } else {
174             result = m_Client->canConsumePacket();
175         }
176         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result);
177         return result;
178     } else {
179         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " no client\n");
180     }
181     return false;
182 }
183
184 bool
185 IsoHandler::iterate() {
186     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) Iterating ISO handler...\n",
187                 this, getTypeString());
188     if(m_State == E_Running) {
189 #if ISOHANDLER_FLUSH_BEFORE_ITERATE
190         flush();
191 #endif
192         m_last_now = m_manager.get1394Service().getCycleTimer();
193         if(raw1394_loop_iterate(m_handle)) {
194             debugError( "IsoHandler (%p): Failed to iterate handler: %s\n",
195                         this, strerror(errno));
196             return false;
197         }
198         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) done interating ISO handler...\n",
199                            this, getTypeString());
200         return true;
201     } else {
202         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) Not iterating a non-running handler...\n",
203                     this, getTypeString());
204         return false;
205     }
206 }
207
208 bool
209 IsoHandler::init()
210 {
211     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoHandler (%p) enter...\n",this);
212     // check the state
213     if(m_State != E_Created) {
214         debugError("Incorrect state, expected E_Created, got %d\n",(int)m_State);
215         return false;
216     }
217
218     // the main handle for the ISO traffic
219     m_handle = raw1394_new_handle_on_port( m_manager.get1394Service().getPort() );
220     if ( !m_handle ) {
221         if ( !errno ) {
222             debugError("libraw1394 not compatible\n");
223         } else {
224             debugError("Could not get 1394 handle: %s\n", strerror(errno) );
225             debugError("Are ieee1394 and raw1394 drivers loaded?\n");
226         }
227         return false;
228     }
229     raw1394_set_userdata(m_handle, static_cast<void *>(this));
230
231     // bus reset handling
232     if(raw1394_busreset_notify (m_handle, RAW1394_NOTIFY_ON)) {
233         debugWarning("Could not enable busreset notification.\n");
234         debugWarning(" Error message: %s\n",strerror(errno));
235         debugWarning("Continuing without bus reset support.\n");
236     } else {
237         // apparently this cannot fail
238         raw1394_set_bus_reset_handler(m_handle, busreset_handler);
239     }
240
241     // update the internal state
242     m_State=E_Initialized;
243     return true;
244 }
245
246 bool IsoHandler::disable()
247 {
248     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) enter...\n",
249                  this, (m_type==eHT_Receive?"Receive":"Transmit"));
250
251     // check state
252     if(m_State == E_Prepared) return true;
253     if(m_State != E_Running) {
254         debugError("Incorrect state, expected E_Running, got %d\n",(int)m_State);
255         return false;
256     }
257
258     // this is put here to try and avoid the
259     // Runaway context problem
260     // don't know if it will help though.
261     raw1394_iso_xmit_sync(m_handle);
262     raw1394_iso_stop(m_handle);
263     m_State = E_Prepared;
264     return true;
265 }
266
267 /**
268  * Bus reset handler
269  *
270  * @return ?
271  */
272
273 int
274 IsoHandler::handleBusReset(unsigned int generation)
275 {
276     debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n");
277
278     #define CSR_CYCLE_TIME            0x200
279     #define CSR_REGISTER_BASE  0xfffff0000000ULL
280     // do a simple read on ourself in order to update the internal structures
281     // this avoids read failures after a bus reset
282     quadlet_t buf=0;
283     raw1394_read(m_handle, raw1394_get_local_id(m_handle),
284                  CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf);
285
286     // notify the client of the fact that we have died
287     m_Client->handlerDied();
288
289     if(!disable()) {
290         debugError("(%p) Could not disable IsoHandler\n", this);
291     }
292
293     // request the manager to update it's shadow map
294     m_manager.requestShadowMapUpdate();
295     return 0;
296 }
297
298 void IsoHandler::dumpInfo()
299 {
300     int channel=-1;
301     if (m_Client) channel=m_Client->getChannel();
302
303     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Handler type................: %s\n",
304             getTypeString());
305     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel...............: %2d, %2d\n",
306             m_manager.get1394Service().getPort(), channel);
307     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer, MaxPacketSize, IRQ..: %4d, %4d, %4d\n",
308             m_buf_packets, m_max_packet_size, m_irq_interval);
309     if (this->getType() == eHT_Transmit) {
310         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Speed, PreBuffers...........: %2d, %2d\n",
311                                             m_speed, m_prebuffers);
312         #ifdef DEBUG
313         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Min ISOXMT bufferfill : %04d\n", m_min_ahead);
314         #endif
315     }
316     #ifdef DEBUG
317     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Last cycle, dropped.........: %4d, %4u\n",
318             m_last_cycle, m_dropped);
319     #endif
320
321 }
322
323 void IsoHandler::setVerboseLevel(int l)
324 {
325     setDebugLevel(l);
326 }
327
328 bool IsoHandler::registerStream(StreamProcessor *stream)
329 {
330     assert(stream);
331     debugOutput( DEBUG_LEVEL_VERBOSE, "registering stream (%p)\n", stream);
332
333     if (m_Client) {
334             debugFatal( "Generic IsoHandlers can have only one client\n");
335             return false;
336     }
337     m_Client=stream;
338     return true;
339 }
340
341 bool IsoHandler::unregisterStream(StreamProcessor *stream)
342 {
343     assert(stream);
344     debugOutput( DEBUG_LEVEL_VERBOSE, "unregistering stream (%p)\n", stream);
345
346     if(stream != m_Client) {
347             debugFatal( "no client registered\n");
348             return false;
349     }
350     m_Client=0;
351     return true;
352 }
353
354 void IsoHandler::flush()
355 {
356     if(m_type == eHT_Receive) {
357         raw1394_iso_recv_flush(m_handle);
358     } else {
359         // do nothing
360     }
361 }
362
363 // ISO packet interface
364 enum raw1394_iso_disposition IsoHandler::putPacket(
365                     unsigned char *data, unsigned int length,
366                     unsigned char channel, unsigned char tag, unsigned char sy,
367                     unsigned int cycle, unsigned int dropped, unsigned int skipped) {
368
369     uint32_t pkt_ctr = cycle << 12;
370
371     // if we assume that one iterate() loop doesn't take longer than 0.5 seconds,
372     // the seconds field won't change while the iterate loop runs
373     // this means that we can preset 'now' before running iterate()
374     uint32_t now_secs = CYCLE_TIMER_GET_SECS(m_last_now);
375     // causality results in the fact that 'now' is always after 'cycle'
376     if(CYCLE_TIMER_GET_CYCLES(m_last_now) < cycle) {
377         // the cycle field has wrapped, substract one second
378         if(now_secs == 0) {
379             now_secs = 127;
380         } else  {
381             now_secs -= 1;
382         }
383     }
384     pkt_ctr |= (now_secs & 0x7F) << 25;
385
386     #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION
387     // add a seconds field
388     uint32_t now = m_manager.get1394Service().getCycleTimer();
389     uint32_t now_secs_ref = CYCLE_TIMER_GET_SECS(now);
390     // causality results in the fact that 'now' is always after 'cycle'
391     if(CYCLE_TIMER_GET_CYCLES(now) < cycle) {
392         // the cycle field has wrapped, substract one second
393         if(now_secs_ref == 0) {
394             now_secs_ref = 127;
395         } else  {
396             now_secs_ref -= 1;
397         }
398     }
399     uint32_t pkt_ctr_ref = cycle << 12;
400     pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25;
401
402     if(pkt_ctr != pkt_ctr_ref) {
403         debugWarning("reconstructed CTR counter discrepancy\n");
404         pkt_ctr=pkt_ctr_ref;
405     }
406     #endif
407
408     // leave the offset field (for now?)
409
410     debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE,
411                        "received packet: length=%d, channel=%d, cycle=%d\n",
412                        length, channel, cycle);
413     #ifdef DEBUG
414     m_packets++;
415     if (length > m_max_packet_size) {
416         debugWarning("(%p, %s) packet too large: len=%u max=%u\n",
417                      this, getTypeString(), length, m_max_packet_size);
418     }
419     if(m_last_cycle == -1) {
420         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %u)\n", getTypeString(), this, cycle);
421     }
422     #endif
423
424     // keep track of dropped cycles
425     int dropped_cycles = 0;
426     if (m_last_cycle != (int)cycle && m_last_cycle != -1) {
427         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
428         #ifdef DEBUG
429         if (dropped_cycles < 0) {
430             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d, 'skipped'=%u\n",
431                          this, dropped_cycles, cycle, m_last_cycle, dropped, skipped);
432         }
433         if (dropped_cycles > 0) {
434             debugOutput(DEBUG_LEVEL_NORMAL,
435                         "(%p) dropped %d packets on cycle %u, 'dropped'=%u, 'skipped'=%u, cycle=%d, m_last_cycle=%d\n",
436                         this, dropped_cycles, cycle, dropped, skipped, cycle, m_last_cycle);
437             m_dropped += dropped_cycles;
438         }
439         #endif
440     }
441     m_last_cycle = cycle;
442
443     // iterate the client if required
444     if(m_Client) {
445         enum raw1394_iso_disposition retval = m_Client->putPacket(data, length, channel, tag, sy, pkt_ctr, dropped_cycles, skipped);
446         if (retval == RAW1394_ISO_OK) {
447             if (m_dont_exit_iterate_loop) {
448                 return RAW1394_ISO_OK;
449             } else {
450                 m_dont_exit_iterate_loop = true;
451                 debugOutput(DEBUG_LEVEL_VERBOSE,
452                                 "(%p) loop exit requested\n",
453                                 this);
454                 return RAW1394_ISO_DEFER;
455             }
456         } else {
457             return retval;
458         }
459     }
460
461     return RAW1394_ISO_OK;
462 }
463
464
465 enum raw1394_iso_disposition
466 IsoHandler::getPacket(unsigned char *data, unsigned int *length,
467                       unsigned char *tag, unsigned char *sy,
468                       int cycle, unsigned int dropped, unsigned int skipped) {
469
470     uint32_t pkt_ctr;
471     if (cycle < 0) {
472         // mark invalid
473         pkt_ctr = 0xFFFFFFFF;
474     } else {
475         pkt_ctr = cycle << 12;
476
477 #if 0 // we don't need this for xmit
478         // if we assume that one iterate() loop doesn't take longer than 0.5 seconds,
479         // the seconds field won't change while the iterate loop runs
480         // this means that we can preset 'now' before running iterate()
481         uint32_t now_secs = CYCLE_TIMER_GET_SECS(m_last_now);
482         // causality results in the fact that 'now' is always after 'cycle'
483         if(CYCLE_TIMER_GET_CYCLES(m_last_now) > (unsigned int)cycle) {
484             // the cycle field has wrapped, add one second
485             now_secs += 1;
486             // no need for this:
487             //if(now_secs == 128) {
488             //    now_secs = 0;
489             //}
490             // since we mask later on
491         }
492         pkt_ctr |= (now_secs & 0x7F) << 25;
493
494         #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION
495         // add a seconds field
496         uint32_t now = m_manager.get1394Service().getCycleTimer();
497         uint32_t now_secs_ref = CYCLE_TIMER_GET_SECS(now);
498         // causality results in the fact that 'now' is always after 'cycle'
499         if(CYCLE_TIMER_GET_CYCLES(now) > (unsigned int)cycle) {
500             // the cycle field has wrapped, add one second
501             now_secs_ref += 1;
502             // no need for this:
503             //if(now_secs == 128) {
504             //    now_secs = 0;
505             //}
506             // since we mask later on
507         }
508         uint32_t pkt_ctr_ref = cycle << 12;
509         pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25;
510    
511         if(pkt_ctr != pkt_ctr_ref) {
512             debugWarning("reconstructed CTR counter discrepancy\n");
513             pkt_ctr=pkt_ctr_ref;
514         }
515         #endif
516 #endif
517     }
518
519     debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE,
520                        "sending packet: length=%d, cycle=%d\n",
521                        *length, cycle);
522
523     #ifdef DEBUG
524     m_packets++;
525     if(m_last_cycle == -1) {
526         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %d)\n", getTypeString(), this, cycle);
527     }
528     #endif
529
530     // keep track of dropped cycles
531     int dropped_cycles = 0;
532     if (m_last_cycle != cycle && m_last_cycle != -1) {
533         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
534         // correct for skipped packets
535         // since those are not dropped, but only delayed
536         dropped_cycles -= skipped;
537
538         #ifdef DEBUG
539         if(skipped) {
540             debugOutput(DEBUG_LEVEL_NORMAL,
541                         "(%p) skipped %d cycles, cycle: %d, last_cycle: %d, dropped: %d\n",
542                         this, skipped, cycle, m_last_cycle, dropped);
543         }
544         if (dropped_cycles < 0) {
545             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d, skipped: %d\n",
546                          this, dropped_cycles, cycle, m_last_cycle, dropped, skipped);
547         }
548         if (dropped_cycles > 0) {
549             debugOutput(DEBUG_LEVEL_NORMAL,
550                         "(%p) dropped %d packets on cycle %u (last_cycle=%u, dropped=%d, skipped: %d)\n",
551                         this, dropped_cycles, cycle, m_last_cycle, dropped, skipped);
552             m_dropped += dropped_cycles - skipped;
553         }
554         #endif
555     }
556     if (cycle >= 0) {
557         m_last_cycle = cycle;
558        
559         #ifdef DEBUG
560 /*        int ahead = diffCycles(cycle, now_cycles);
561         if (ahead < m_min_ahead) m_min_ahead = ahead;
562 */
563         #endif
564     }
565
566     if(m_Client) {
567         enum raw1394_iso_disposition retval;
568         retval = m_Client->getPacket(data, length, tag, sy, pkt_ctr, dropped, skipped, m_max_packet_size);
569         #ifdef DEBUG
570         if (*length > m_max_packet_size) {
571             debugWarning("(%p, %s) packet too large: len=%u max=%u\n",
572                          this, getTypeString(), *length, m_max_packet_size);
573         }
574         #endif
575         if (retval == RAW1394_ISO_OK) {
576             if (m_dont_exit_iterate_loop) {
577                 return RAW1394_ISO_OK;
578             } else {
579                 m_dont_exit_iterate_loop = true;
580                 debugOutput(DEBUG_LEVEL_VERBOSE,
581                                 "(%p) loop exit requested\n",
582                                 this);
583                 return RAW1394_ISO_DEFER;
584             }
585         } else {
586             return retval;
587         }
588     }
589
590     *tag = 0;
591     *sy = 0;
592     *length = 0;
593     return RAW1394_ISO_OK;
594 }
595
596 bool IsoHandler::prepare()
597 {
598     // check the state
599     if(m_State != E_Initialized) {
600         debugError("Incorrect state, expected E_Initialized, got %d\n",(int)m_State);
601         return false;
602     }
603
604     // Don't call until libraw1394's raw1394_new_handle() function has been
605     // fixed to correctly initialise the iso_packet_infos field.  Bug is
606     // confirmed present in libraw1394 1.2.1.
607     //     raw1394_iso_shutdown(m_handle);
608     m_State = E_Prepared;
609
610     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso handler (%p, client=%p)\n", this, m_Client);
611     dumpInfo();
612     if (getType() == eHT_Receive) {
613         if(m_irq_interval > 1) {
614             if(raw1394_iso_recv_init(m_handle,
615                                     iso_receive_handler,
616                                     m_buf_packets,
617                                     m_max_packet_size,
618                                     m_Client->getChannel(),
619                                     RAW1394_DMA_BUFFERFILL,
620 //                                     RAW1394_DMA_PACKET_PER_BUFFER,
621                                     m_irq_interval)) {
622                 debugFatal("Could not do receive initialisation (DMA_BUFFERFILL)!\n" );
623                 debugFatal("  %s\n",strerror(errno));
624                 return false;
625             }
626         } else {
627             if(raw1394_iso_recv_init(m_handle,
628                                     iso_receive_handler,
629                                     m_buf_packets,
630                                     m_max_packet_size,
631                                     m_Client->getChannel(),
632                                     RAW1394_DMA_PACKET_PER_BUFFER,
633                                     m_irq_interval)) {
634                 debugFatal("Could not do receive initialisation (PACKET_PER_BUFFER)!\n" );
635                 debugFatal("  %s\n",strerror(errno));
636                 return false;
637             }
638         }
639         return true;
640     } else {
641         if(raw1394_iso_xmit_init(m_handle,
642                                 iso_transmit_handler,
643                                 m_buf_packets,
644                                 m_max_packet_size,
645                                 m_Client->getChannel(),
646                                 m_speed,
647                                 m_irq_interval)) {
648             debugFatal("Could not do xmit initialisation!\n" );
649             return false;
650         }
651         return true;
652     }
653 }
654
655 bool IsoHandler::enable(int cycle)
656 {
657     debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d\n", cycle);
658     // check the state
659     if(m_State != E_Prepared) {
660         if(!prepare()) {
661             debugFatal("Could not prepare handler\n");
662             return false;
663         }
664     }
665
666     if (getType() == eHT_Receive) {
667         if(raw1394_iso_recv_start(m_handle, cycle, -1, 0)) {
668             debugFatal("Could not start receive handler (%s)\n",strerror(errno));
669             dumpInfo();
670             return false;
671         }
672     } else {
673         if(raw1394_iso_xmit_start(m_handle, cycle, m_prebuffers)) {
674             debugFatal("Could not start xmit handler (%s)\n",strerror(errno));
675             dumpInfo();
676             return false;
677         }
678     }
679
680 #ifdef DEBUG
681     m_min_ahead = 7999;
682 #endif
683     m_State = E_Running;
684     return true;
685 }
686
687 /**
688  * @brief convert a EHandlerType to a string
689  * @param t the type
690  * @return a char * describing the state
691  */
692 const char *
693 IsoHandler::eHTToString(enum EHandlerType t) {
694     switch (t) {
695         case eHT_Receive: return "Receive";
696         case eHT_Transmit: return "Transmit";
697         default: return "error: unknown type";
698     }
699 }
Note: See TracBrowser for help on using the browser.