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

Revision 753, 18.6 kB (checked in by ppalmers, 13 years ago)

have separate threads for every handler

Line 
1 /*
2  * Copyright (C) 2005-2007 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 3 of the License, or
12  * (at your option) any later version.
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 "IsoHandler.h"
25 #include "ieee1394service.h"
26
27 #include "libstreaming/generic/StreamProcessor.h"
28 #include "libutil/PosixThread.h"
29
30 #include <errno.h>
31 #include <netinet/in.h>
32 #include <assert.h>
33 #include <unistd.h>
34 #include <string.h>
35
36 #include <iostream>
37 using namespace std;
38 using namespace Streaming;
39
40 IMPL_DEBUG_MODULE( IsoHandler, IsoHandler, DEBUG_LEVEL_NORMAL );
41
42 /* the C callbacks */
43 enum raw1394_iso_disposition
44 IsoXmitHandler::iso_transmit_handler(raw1394handle_t handle,
45         unsigned char *data, unsigned int *length,
46         unsigned char *tag, unsigned char *sy,
47         int cycle, unsigned int dropped) {
48
49     IsoXmitHandler *xmitHandler=static_cast<IsoXmitHandler *>(raw1394_get_userdata(handle));
50     assert(xmitHandler);
51
52     return xmitHandler->getPacket(data, length, tag, sy, cycle, dropped);
53 }
54
55 enum raw1394_iso_disposition
56 IsoRecvHandler::iso_receive_handler(raw1394handle_t handle, unsigned char *data,
57                         unsigned int length, unsigned char channel,
58                         unsigned char tag, unsigned char sy, unsigned int cycle,
59                         unsigned int dropped) {
60
61     IsoRecvHandler *recvHandler=static_cast<IsoRecvHandler *>(raw1394_get_userdata(handle));
62     assert(recvHandler);
63
64     return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped);
65 }
66
67 int IsoHandler::busreset_handler(raw1394handle_t handle, unsigned int generation)
68 {
69     debugOutput( DEBUG_LEVEL_VERBOSE, "Busreset happened, generation %d...\n", generation);
70
71     IsoHandler *handler=static_cast<IsoHandler *>(raw1394_get_userdata(handle));
72     assert(handler);
73     return handler->handleBusReset(generation);
74 }
75
76
77 /* Base class implementation */
78 IsoHandler::IsoHandler(IsoHandlerManager& manager)
79    : m_manager(manager)
80    , m_handle(0)
81    , m_buf_packets(400)
82    , m_max_packet_size(1024)
83    , m_irq_interval(-1)
84    , m_packetcount(0)
85    , m_dropped(0)
86    , m_Client(0)
87    , m_poll_timeout( 100 )
88    , m_realtime ( false )
89    , m_priority ( 0 )
90    , m_Thread ( NULL )
91    , m_State(E_Created)
92 {
93 }
94
95 IsoHandler::IsoHandler(IsoHandlerManager& manager, unsigned int buf_packets, unsigned int max_packet_size, int irq)
96    : m_manager(manager)
97    , m_handle(0)
98    , m_buf_packets(buf_packets)
99    , m_max_packet_size( max_packet_size)
100    , m_irq_interval(irq)
101    , m_packetcount(0)
102    , m_dropped(0)
103    , m_Client(0)
104    , m_poll_timeout( 100 )
105    , m_realtime ( false )
106    , m_priority ( 0 )
107    , m_Thread ( NULL )
108    , m_State(E_Created)
109 {
110 }
111
112 IsoHandler::~IsoHandler() {
113     if (m_Thread) {
114         m_Thread->Stop();
115         delete m_Thread;
116     }
117 // Don't call until libraw1394's raw1394_new_handle() function has been
118 // fixed to correctly initialise the iso_packet_infos field.  Bug is
119 // confirmed present in libraw1394 1.2.1.  In any case,
120 // raw1394_destroy_handle() will do any iso system shutdown required.
121 //     raw1394_iso_shutdown(m_handle);
122     if(m_handle) {
123         if (m_State == E_Running) {
124             disable();
125         }
126         raw1394_destroy_handle(m_handle);
127     }
128 }
129
130 bool
131 IsoHandler::Init() {
132     debugOutput( DEBUG_LEVEL_VERBOSE, "%p: Init thread...\n", this);
133     m_poll_fd.fd = getFileDescriptor();
134     m_poll_fd.revents = 0;
135     if (isEnabled()) {
136         m_poll_fd.events = POLLIN;
137     } else {
138         m_poll_fd.events = 0;
139     }
140     return true;
141 }
142
143 bool
144 IsoHandler::Execute() {
145     int err;
146
147     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "%p: Execute thread...\n", this);
148     // bypass if not running
149     if (m_State != E_Running) {
150         debugOutput( DEBUG_LEVEL_VERBOSE, "%p: not polling since not running...\n", this);
151         usleep(m_poll_timeout * 1000);
152         debugOutput( DEBUG_LEVEL_VERBOSE, "%p: done sleeping...\n", this);
153         return true;
154     }
155
156     err = poll(&m_poll_fd, 1, m_poll_timeout);
157     if (err == -1) {
158         if (errno == EINTR) {
159             return true;
160         }
161         debugFatal("%p, poll error: %s\n", this, strerror (errno));
162         return false;
163     }
164
165     if (m_poll_fd.revents & POLLERR) {
166         debugWarning("error on fd for %p\n", this);
167     }
168
169     if (m_poll_fd.revents & POLLHUP) {
170         debugWarning("hangup on fd for %p\n",this);
171     }
172
173     if(m_poll_fd.revents & (POLLIN)) {
174         iterate();
175     }
176
177     return true;
178 }
179
180 bool
181 IsoHandler::setThreadParameters(bool rt, int priority) {
182     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) (rt=%d, prio=%d)...\n", this, rt, priority);
183     if (priority > 98) priority = 98; // cap the priority
184     m_realtime = rt;
185     m_priority = priority;
186
187     if (m_Thread) {
188         if (m_realtime) {
189             m_Thread->AcquireRealTime(m_priority);
190         } else {
191             m_Thread->DropRealTime();
192         }
193     }
194     return true;
195 }
196
197 bool
198 IsoHandler::iterate() {
199     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "IsoHandler (%p) iterate...\n",this);
200     if(raw1394_loop_iterate(m_handle)) {
201         debugOutput( DEBUG_LEVEL_VERBOSE,
202                      "IsoHandler (%p): Failed to iterate handler: %s\n",
203                      this,strerror(errno));
204         return false;
205     } else {
206         return true;
207     }
208 }
209
210 bool
211 IsoHandler::init()
212 {
213     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoHandler (%p) enter...\n",this);
214     // check the state
215     if(m_State != E_Created) {
216         debugError("Incorrect state, expected E_Created, got %d\n",(int)m_State);
217         return false;
218     }
219
220     // the main handle for the ISO traffic
221     m_handle = raw1394_new_handle_on_port( m_manager.get1394Service().getPort() );
222     if ( !m_handle ) {
223         if ( !errno ) {
224             debugError("libraw1394 not compatible\n");
225         } else {
226             debugError("Could not get 1394 handle: %s\n", strerror(errno) );
227             debugError("Are ieee1394 and raw1394 drivers loaded?\n");
228         }
229         return false;
230     }
231     raw1394_set_userdata(m_handle, static_cast<void *>(this));
232
233     // bus reset handling
234     if(raw1394_busreset_notify (m_handle, RAW1394_NOTIFY_ON)) {
235         debugWarning("Could not enable busreset notification.\n");
236         debugWarning(" Error message: %s\n",strerror(errno));
237         debugWarning("Continuing without bus reset support.\n");
238     } else {
239         // apparently this cannot fail
240         raw1394_set_bus_reset_handler(m_handle, busreset_handler);
241     }
242
243     // create a thread to iterate ourselves
244     debugOutput( DEBUG_LEVEL_VERBOSE, "Start thread for %p...\n", this);
245     m_Thread = new Util::PosixThread(this, m_realtime, m_priority,
246                                      PTHREAD_CANCEL_DEFERRED);
247     if(!m_Thread) {
248         debugFatal("No thread\n");
249         return false;
250     }
251     if (m_Thread->Start() != 0) {
252         debugFatal("Could not start update thread\n");
253         return false;
254     }
255
256     // update the internal state
257     m_State=E_Initialized;
258     return true;
259 }
260
261 bool IsoHandler::prepare()
262 {
263     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoHandler (%p) prepare...\n", this);
264     // check the state
265     if(m_State != E_Initialized) {
266         debugError("Incorrect state, expected E_Initialized, got %d\n",(int)m_State);
267         return false;
268     }
269     // Don't call until libraw1394's raw1394_new_handle() function has been
270     // fixed to correctly initialise the iso_packet_infos field.  Bug is
271     // confirmed present in libraw1394 1.2.1.
272 //     raw1394_iso_shutdown(m_handle);
273     m_State = E_Prepared;
274     return true;
275 }
276
277 bool IsoHandler::enable(int cycle)
278 {
279     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
280     m_poll_fd.events = POLLIN;
281     m_State = E_Running;
282     return true;
283 }
284
285 bool IsoHandler::disable()
286 {
287     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
288
289     // check state
290     if(m_State == E_Prepared) return true;
291     if(m_State != E_Running) {
292         debugError("Incorrect state, expected E_Running, got %d\n",(int)m_State);
293         return false;
294     }
295
296     m_poll_fd.events = 0;
297
298     // this is put here to try and avoid the
299     // Runaway context problem
300     // don't know if it will help though.
301     raw1394_iso_xmit_sync(m_handle);
302     raw1394_iso_stop(m_handle);
303     m_State = E_Prepared;
304     return true;
305 }
306
307 /**
308  * Bus reset handler
309  *
310  * @return ?
311  */
312
313 int IsoHandler::handleBusReset(unsigned int generation) {
314     debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n");
315
316     #define CSR_CYCLE_TIME            0x200
317     #define CSR_REGISTER_BASE  0xfffff0000000ULL
318     // do a simple read on ourself in order to update the internal structures
319     // this avoids read failures after a bus reset
320     quadlet_t buf=0;
321     raw1394_read(m_handle, raw1394_get_local_id(m_handle),
322                  CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf);
323     return 0;
324 }
325
326 void IsoHandler::dumpInfo()
327 {
328     int channel=-1;
329     if (m_Client) channel=m_Client->getChannel();
330
331     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Handler type................: %s\n",
332             (this->getType()==EHT_Receive ? "Receive" : "Transmit"));
333     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel...............: %2d, %2d\n",
334             m_manager.get1394Service().getPort(), channel);
335     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer, MaxPacketSize, IRQ..: %4d, %4d, %4d\n",
336             m_buf_packets, m_max_packet_size, m_irq_interval);
337     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Packet count................: %10d (%5d dropped)\n",
338             this->getPacketCount(), this->getDroppedCount());
339 }
340
341 void IsoHandler::setVerboseLevel(int l)
342 {
343     setDebugLevel(l);
344     if(m_Thread) m_Thread->setVerboseLevel(l);
345 }
346
347 bool IsoHandler::registerStream(StreamProcessor *stream)
348 {
349     assert(stream);
350     debugOutput( DEBUG_LEVEL_VERBOSE, "registering stream (%p)\n", stream);
351
352     if (m_Client) {
353             debugFatal( "Generic IsoHandlers can have only one client\n");
354             return false;
355     }
356     m_Client=stream;
357     return true;
358 }
359
360 bool IsoHandler::unregisterStream(StreamProcessor *stream)
361 {
362     assert(stream);
363     debugOutput( DEBUG_LEVEL_VERBOSE, "unregistering stream (%p)\n", stream);
364
365     if(stream != m_Client) {
366             debugFatal( "no client registered\n");
367             return false;
368     }
369     m_Client=0;
370     return true;
371 }
372
373 /* Child class implementations */
374
375 IsoRecvHandler::IsoRecvHandler(IsoHandlerManager& manager)
376                 : IsoHandler(manager)
377 {
378     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
379 }
380 IsoRecvHandler::IsoRecvHandler(IsoHandlerManager& manager, unsigned int buf_packets,
381                                unsigned int max_packet_size, int irq)
382                 : IsoHandler(manager, buf_packets,max_packet_size,irq)
383 {
384     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
385
386 }
387 IsoRecvHandler::~IsoRecvHandler()
388 {
389
390 }
391
392 void IsoRecvHandler::flush()
393 {
394     raw1394_iso_recv_flush(m_handle);
395 }
396
397 bool
398 IsoRecvHandler::init() {
399     debugOutput( DEBUG_LEVEL_VERBOSE, "init recv handler %p\n",this);
400
401     if(!(IsoHandler::init())) {
402         return false;
403     }
404     return true;
405
406 }
407
408 enum raw1394_iso_disposition IsoRecvHandler::putPacket(
409                     unsigned char *data, unsigned int length,
410                     unsigned char channel, unsigned char tag, unsigned char sy,
411                     unsigned int cycle, unsigned int dropped) {
412
413     debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
414                  "received packet: length=%d, channel=%d, cycle=%d\n",
415                  length, channel, cycle );
416     m_packetcount++;
417     m_dropped+=dropped;
418
419     if(m_Client) {
420         return m_Client->putPacket(data, length, channel, tag, sy, cycle, dropped);
421     }
422
423     return RAW1394_ISO_OK;
424 }
425
426 bool IsoRecvHandler::prepare()
427 {
428     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso receive handler (%p, client=%p)\n", this, m_Client);
429     // prepare the generic IsoHandler
430     if(!IsoHandler::prepare()) {
431         return false;
432     }
433     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso receive handler (%p)\n",this);
434     debugOutput( DEBUG_LEVEL_VERBOSE, " Buffers         : %d \n", m_buf_packets);
435     debugOutput( DEBUG_LEVEL_VERBOSE, " Max Packet size : %d \n", m_max_packet_size);
436     debugOutput( DEBUG_LEVEL_VERBOSE, " Channel         : %d \n", m_Client->getChannel());
437     debugOutput( DEBUG_LEVEL_VERBOSE, " Irq interval    : %d \n", m_irq_interval);
438     debugOutput( DEBUG_LEVEL_VERBOSE, " Mode            : %s \n",
439                                (m_irq_interval > 1)?"DMA_BUFFERFILL":"PACKET_PER_BUFFER");
440
441     if(m_irq_interval > 1) {
442         if(raw1394_iso_recv_init(m_handle,
443                                 iso_receive_handler,
444                                 m_buf_packets,
445                                 m_max_packet_size,
446                                 m_Client->getChannel(),
447                                 RAW1394_DMA_BUFFERFILL,
448                                 m_irq_interval)) {
449             debugFatal("Could not do receive initialisation!\n" );
450             debugFatal("  %s\n",strerror(errno));
451
452             return false;
453         }
454     } else {
455         if(raw1394_iso_recv_init(m_handle,
456                                 iso_receive_handler,
457                                 m_buf_packets,
458                                 m_max_packet_size,
459                                 m_Client->getChannel(),
460                                 RAW1394_DMA_PACKET_PER_BUFFER,
461                                 m_irq_interval)) {
462             debugFatal("Could not do receive initialisation!\n" );
463             debugFatal("  %s\n",strerror(errno));
464
465             return false;
466         }
467     }
468     return true;
469 }
470
471 bool IsoRecvHandler::enable(int cycle)
472 {
473     debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d\n", cycle);
474     // check the state
475     if(m_State != E_Prepared) {
476         if(!prepare()) {
477             debugFatal("Could not prepare recv handler\n");
478             return false;
479         }
480     }
481     if(raw1394_iso_recv_start(m_handle, cycle, -1, 0)) {
482         debugFatal("Could not start receive handler (%s)\n",strerror(errno));
483         dumpInfo();
484         return false;
485     }
486     // start the generic IsoHandler
487     if(!IsoHandler::enable(cycle)) {
488         return false;
489     }
490     return true;
491 }
492
493 int IsoRecvHandler::handleBusReset(unsigned int generation) {
494     debugOutput( DEBUG_LEVEL_VERBOSE, "handle bus reset...\n");
495
496     //TODO: implement busreset
497
498     // pass on the busreset signal
499     if(IsoHandler::handleBusReset(generation)) {
500         return -1;
501     }
502     return 0;
503 }
504
505 /* ----------------- XMIT --------------- */
506
507 IsoXmitHandler::IsoXmitHandler(IsoHandlerManager& manager)
508                 : IsoHandler(manager), m_prebuffers(0)
509 {
510     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n");
511
512 }
513 IsoXmitHandler::IsoXmitHandler(IsoHandlerManager& manager, unsigned int buf_packets,
514                                unsigned int max_packet_size, int irq)
515                 : IsoHandler(manager, buf_packets, max_packet_size,irq),
516                   m_speed(RAW1394_ISO_SPEED_400), m_prebuffers(0)
517 {
518     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n");
519
520 }
521 IsoXmitHandler::IsoXmitHandler(IsoHandlerManager& manager, unsigned int buf_packets,
522                                unsigned int max_packet_size, int irq,
523                                enum raw1394_iso_speed speed)
524                 : IsoHandler(manager, buf_packets,max_packet_size,irq),
525                   m_speed(speed), m_prebuffers(0)
526 {
527     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n");
528
529 }
530
531 IsoXmitHandler::~IsoXmitHandler()
532 {
533     // handle cleanup is done in the IsoHanlder destructor
534 }
535
536 bool
537 IsoXmitHandler::init() {
538
539     debugOutput( DEBUG_LEVEL_VERBOSE, "init xmit handler %p\n",this);
540
541     if(!(IsoHandler::init())) {
542         return false;
543     }
544
545     return true;
546 }
547
548 bool IsoXmitHandler::prepare()
549 {
550     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso transmit handler (%p, client=%p)\n", this, m_Client);
551     if(!(IsoHandler::prepare())) {
552         return false;
553     }
554
555     debugOutput( DEBUG_LEVEL_VERBOSE, " Buffers         : %d \n",m_buf_packets);
556     debugOutput( DEBUG_LEVEL_VERBOSE, " Max Packet size : %d \n",m_max_packet_size);
557     debugOutput( DEBUG_LEVEL_VERBOSE, " Channel         : %d \n",m_Client->getChannel());
558     debugOutput( DEBUG_LEVEL_VERBOSE, " Speed           : %d \n",m_speed);
559     debugOutput( DEBUG_LEVEL_VERBOSE, " Irq interval    : %d \n",m_irq_interval);
560     if(raw1394_iso_xmit_init(m_handle,
561                              iso_transmit_handler,
562                              m_buf_packets,
563                              m_max_packet_size,
564                              m_Client->getChannel(),
565                              m_speed,
566                              m_irq_interval)) {
567         debugFatal("Could not do xmit initialisation!\n" );
568
569         return false;
570     }
571     return true;
572 }
573
574 bool IsoXmitHandler::enable(int cycle)
575 {
576     debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d, %d prebuffers\n",
577         cycle, m_prebuffers);
578     // check the state
579     if(m_State != E_Prepared) {
580         if(!prepare()) {
581             debugFatal("Could not prepare xmit handler\n");
582             return false;
583         }
584     }
585     if(raw1394_iso_xmit_start(m_handle, cycle, m_prebuffers)) {
586         debugFatal("Could not start xmit handler (%s)\n",strerror(errno));
587         dumpInfo();
588         return false;
589     }
590     if(!(IsoHandler::enable(cycle))) {
591         return false;
592     }
593     return true;
594 }
595
596 enum raw1394_iso_disposition IsoXmitHandler::getPacket(
597                     unsigned char *data, unsigned int *length,
598                     unsigned char *tag, unsigned char *sy,
599                     int cycle, unsigned int dropped) {
600
601     debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
602                     "sending packet: length=%d, cycle=%d\n",
603                     *length, cycle );
604     m_packetcount++;
605     m_dropped+=dropped;
606
607     if(m_Client) {
608         return m_Client->getPacket(data, length, tag, sy, cycle, dropped, m_max_packet_size);
609     }
610     return RAW1394_ISO_OK;
611 }
612
613 int IsoXmitHandler::handleBusReset(unsigned int generation) {
614     debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n");
615     //TODO: implement busreset
616     // pass on the busreset signal
617     if(IsoHandler::handleBusReset(generation)) {
618             return -1;
619     }
620     return 0;
621 }
622
623 void IsoXmitHandler::dumpInfo()
624 {
625     IsoHandler::dumpInfo();
626     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Speed, PreBuffers...........: %2d, %2d\n",
627                                           m_speed, m_prebuffers);
628 }
Note: See TracBrowser for help on using the browser.