root/trunk/libffado/src/devicemanager.cpp

Revision 2811, 42.8 kB (checked in by jwoithe, 1 year 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).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Copyright (C) 2005-2008 by Daniel Wagner
3  * Copyright (C) 2005-2008 by Pieter Palmers
4  *
5  * This file is part of FFADO
6  * FFADO = Free FireWire (pro-)audio drivers for Linux
7  *
8  * FFADO is based upon FreeBoB.
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "config.h"
26 #include "fbtypes.h"
27
28 #include "devicemanager.h"
29 #include "ffadodevice.h"
30 #include "DeviceStringParser.h"
31
32 #include "libieee1394/configrom.h"
33 #include "libieee1394/ieee1394service.h"
34 #include "libieee1394/IsoHandlerManager.h"
35
36 #include "libstreaming/generic/StreamProcessor.h"
37 #include "libstreaming/StreamProcessorManager.h"
38
39 #include "debugmodule/debugmodule.h"
40
41 #include "libutil/PosixMutex.h"
42
43 #ifdef ENABLE_BEBOB
44 #include "bebob/bebob_avdevice.h"
45 #endif
46
47 #ifdef ENABLE_GENERICAVC
48     #include "genericavc/avc_avdevice.h"
49 #endif
50
51 #ifdef ENABLE_FIREWORKS
52     #include "fireworks/fireworks_device.h"
53 #endif
54
55 #ifdef ENABLE_OXFORD
56     #include "oxford/oxford_device.h"
57 #endif
58
59 #ifdef ENABLE_BOUNCE
60 #include "bounce/bounce_avdevice.h"
61 #include "bounce/bounce_slave_avdevice.h"
62 #endif
63
64 #ifdef ENABLE_MOTU
65 #include "motu/motu_avdevice.h"
66 #endif
67
68 #ifdef ENABLE_RME
69 #include "rme/rme_avdevice.h"
70 #endif
71
72 #ifdef ENABLE_DICE
73 #include "dice/dice_avdevice.h"
74 #endif
75
76 #ifdef ENABLE_METRIC_HALO
77 #include "metrichalo/mh_avdevice.h"
78 #endif
79
80 #include <iostream>
81 #include <sstream>
82
83 #include <algorithm>
84
85 using namespace std;
86
87 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
88
89 DeviceManager::DeviceManager()
90     : Control::Container(NULL, "devicemanager") // this is the control root node
91     , m_DeviceListLock( new Util::PosixMutex("DEVLST") )
92     , m_BusResetLock( new Util::PosixMutex("DEVBR") )
93     , m_processorManager( new Streaming::StreamProcessorManager( *this ) )
94     , m_deviceStringParser( new DeviceStringParser() )
95     , m_configuration ( new Util::Configuration() )
96     , m_used_cache_last_time( false )
97     , m_thread_realtime( false )
98     , m_thread_priority( 0 )
99 {
100     addOption(Util::OptionContainer::Option("slaveMode", false));
101     addOption(Util::OptionContainer::Option("snoopMode", false));
102 }
103
104 DeviceManager::~DeviceManager()
105 {
106     // save configuration
107     if(!m_configuration->save()) {
108         debugWarning("could not save configuration\n");
109     }
110
111     m_BusResetLock->Lock(); // make sure we are not handling a busreset.
112     m_DeviceListLock->Lock(); // make sure nobody is using this
113     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
114           it != m_avDevices.end();
115           ++it )
116     {
117         if (!deleteElement(*it)) {
118             debugWarning("failed to remove Device from Control::Container\n");
119         }
120         delete *it;
121     }
122     m_DeviceListLock->Unlock();
123
124     // the SP's are automatically unregistered from the SPM
125     delete m_processorManager;
126
127     // the device list is empty, so wake up any waiting
128     // reset handlers
129     m_BusResetLock->Unlock();
130
131     // remove the bus-reset handlers
132     for ( FunctorVectorIterator it = m_busreset_functors.begin();
133           it != m_busreset_functors.end();
134           ++it )
135     {
136         delete *it;
137     }
138
139     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
140           it != m_1394Services.end();
141           ++it )
142     {
143         delete *it;
144     }
145
146     delete m_DeviceListLock;
147     delete m_BusResetLock;
148     delete m_deviceStringParser;
149 }
150
151 bool
152 DeviceManager::setThreadParameters(bool rt, int priority) {
153     if (!m_processorManager->setThreadParameters(rt, priority)) {
154         debugError("Could not set processor manager thread parameters\n");
155         return false;
156     }
157     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
158           it != m_1394Services.end();
159           ++it )
160     {
161         if (!(*it)->setThreadParameters(rt, priority)) {
162             debugError("Could not set 1394 service thread parameters\n");
163             return false;
164         }
165     }
166     m_thread_realtime = rt;
167     m_thread_priority = priority;
168     return true;
169 }
170
171 bool
172 DeviceManager::initialize()
173 {
174     assert(m_1394Services.size() == 0);
175     assert(m_busreset_functors.size() == 0);
176
177     m_configuration->openFile( "temporary", Util::Configuration::eFM_Temporary );
178     m_configuration->openFile( USER_CONFIG_FILE, Util::Configuration::eFM_ReadWrite );
179     m_configuration->openFile( SYSTEM_CONFIG_FILE, Util::Configuration::eFM_ReadOnly );
180
181     int nb_detected_ports = Ieee1394Service::detectNbPorts();
182     if (nb_detected_ports < 0) {
183         debugFatal("Failed to detect the number of 1394 adapters. Is the IEEE1394 stack loaded (raw1394)?\n");
184         return false;
185     }
186     if (nb_detected_ports == 0) {
187         debugFatal("No FireWire adapters (ports) found.\n");
188         return false;
189     }
190     debugOutput( DEBUG_LEVEL_VERBOSE, "Found %d FireWire adapters (ports)\n", nb_detected_ports);
191     for (unsigned int port = 0; port < (unsigned int)nb_detected_ports; port++) {
192         Ieee1394Service* tmp1394Service = new Ieee1394Service();
193         if ( !tmp1394Service ) {
194             debugFatal( "Could not create Ieee1349Service object for port %d\n", port );
195             return false;
196         }
197         tmp1394Service->setVerboseLevel( getDebugLevel() );
198         m_1394Services.push_back(tmp1394Service);
199
200         if(!tmp1394Service->useConfiguration(m_configuration)) {
201             debugWarning("Could not load config to 1394service\n");
202         }
203
204         tmp1394Service->setThreadParameters(m_thread_realtime, m_thread_priority);
205         if ( !tmp1394Service->initialize( port ) ) {
206             debugFatal( "Could not initialize Ieee1349Service object for port %d\n", port );
207             return false;
208         }
209         // add the bus reset handler
210         Util::Functor* tmp_busreset_functor = new Util::MemberFunctor1< DeviceManager*,
211                     void (DeviceManager::*)(Ieee1394Service &), Ieee1394Service & >
212                     ( this, &DeviceManager::busresetHandler, *tmp1394Service, false );
213         if ( !tmp_busreset_functor ) {
214             debugFatal( "Could not create busreset handler for port %d\n", port );
215             return false;
216         }
217         m_busreset_functors.push_back(tmp_busreset_functor);
218
219         tmp1394Service->addBusResetHandler( tmp_busreset_functor );
220     }
221
222     return true;
223 }
224
225 bool
226 DeviceManager::addSpecString(char *s) {
227     std::string spec = s;
228     if(isSpecStringValid(spec)) {
229         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding spec string %s\n", spec.c_str());
230         assert(m_deviceStringParser);
231         m_deviceStringParser->parseString(spec);
232         return true;
233     } else {
234         debugError("Invalid spec string: %s\n", spec.c_str());
235         return false;
236     }
237 }
238
239 bool
240 DeviceManager::isSpecStringValid(std::string s) {
241     assert(m_deviceStringParser);
242     return m_deviceStringParser->isValidString(s);
243 }
244
245 void
246 DeviceManager::busresetHandler(Ieee1394Service &service)
247 {
248     // serialize bus reset handling since it can be that a new one occurs while we're
249     // doing stuff.
250     debugOutput( DEBUG_LEVEL_NORMAL, "Bus reset detected on service %p...\n", &service );
251     Util::MutexLockHelper lock(*m_BusResetLock);
252     debugOutput( DEBUG_LEVEL_NORMAL, " handling busreset...\n" );
253
254     // FIXME: what if the devices are gone? (device should detect this!)
255     // propagate the bus reset to all avDevices
256     m_DeviceListLock->Lock(); // make sure nobody is using this
257     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
258           it != m_avDevices.end();
259           ++it )
260     {
261         if(&service == &((*it)->get1394Service())) {
262             debugOutput(DEBUG_LEVEL_NORMAL,
263                         "issue busreset on device GUID %s\n",
264                         (*it)->getConfigRom().getGuidString().c_str());
265             (*it)->handleBusReset();
266         } else {
267             debugOutput(DEBUG_LEVEL_NORMAL,
268                         "skipping device GUID %s since not on service %p\n",
269                         (*it)->getConfigRom().getGuidString().c_str(), &service);
270         }
271     }
272     m_DeviceListLock->Unlock();
273
274     // now that the devices have been updates, we can request to update the iso streams
275     if(!service.getIsoHandlerManager().handleBusReset()) {
276         debugError("IsoHandlerManager failed to handle busreset\n");
277     }
278
279     // notify the streamprocessormanager of the busreset
280 //     if(m_processorManager) {
281 //         m_processorManager->handleBusReset(service);
282 //     } else {
283 //         debugWarning("No valid SPM\n");
284 //     }
285
286     // rediscover to find new devices
287     // (only for the control server ATM, streaming can't dynamically add/remove devices)
288     if(!discover(m_used_cache_last_time, true)) {
289         debugError("Could not rediscover devices\n");
290     }
291
292     // notify any clients
293     signalNotifiers(m_busResetNotifiers);
294
295     // display the new state
296     if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
297         showDeviceInfo();
298     }
299 }
300
301 void
302 DeviceManager::signalNotifiers(notif_vec_t& list)
303 {
304     for ( notif_vec_t::iterator it = list.begin();
305           it != list.end();
306           ++it )
307     {
308         Util::Functor* func = *it;
309         debugOutput( DEBUG_LEVEL_VERBOSE, " running notifier %p...\n", func );
310         ( *func )();
311     }
312 }
313
314 bool
315 DeviceManager::registerNotification(notif_vec_t& list, Util::Functor *handler)
316 {
317     debugOutput( DEBUG_LEVEL_VERBOSE, "register %p...\n", handler);
318     assert(handler);
319     for ( notif_vec_t::iterator it = list.begin();
320       it != list.end();
321       ++it )
322     {
323         if ( *it == handler ) {
324             debugOutput(DEBUG_LEVEL_VERBOSE, "already registered\n");
325             return false;
326         }
327     }
328     list.push_back(handler);
329     return true;
330 }
331
332 bool
333 DeviceManager::unregisterNotification(notif_vec_t& list, Util::Functor *handler)
334 {
335     debugOutput( DEBUG_LEVEL_VERBOSE, "unregister %p...\n", handler);
336     assert(handler);
337
338     for ( notif_vec_t::iterator it = list.begin();
339       it != list.end();
340       ++it )
341     {
342         if ( *it == handler ) {
343             list.erase(it);
344             return true;
345         }
346     }
347     debugError("Could not find handler (%p)\n", handler);
348     return false; //not found
349 }
350
351 bool
352 DeviceManager::discover( bool useCache, bool rediscover )
353 {
354     debugOutput( DEBUG_LEVEL_NORMAL, "Starting discovery...\n" );
355     useCache = useCache && ENABLE_DISCOVERY_CACHE;
356     m_used_cache_last_time = useCache;
357     bool slaveMode=false;
358     if(!getOption("slaveMode", slaveMode)) {
359         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
360     }
361     bool snoopMode=false;
362     if(!getOption("snoopMode", snoopMode)) {
363         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
364     }
365
366     setVerboseLevel(getDebugLevel());
367
368     // FIXME: it could be that a 1394service has disappeared (cardbus)
369
370     ConfigRomVector configRoms;
371     // build a list of configroms on the bus.
372     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
373         it != m_1394Services.end();
374         ++it )
375     {
376         Ieee1394Service *portService = *it;
377         for ( fb_nodeid_t nodeId = 0;
378             nodeId < portService->getNodeCount();
379             ++nodeId )
380         {
381             debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
382
383             if (nodeId == portService->getLocalNodeId()) {
384                 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
385                 continue;
386             }
387
388             ConfigRom * configRom = new ConfigRom( *portService, nodeId );
389             if ( !configRom->initialize() ) {
390                 // \todo If a PHY on the bus is in power safe mode then
391                 // the config rom is missing. So this might be just
392                 // such this case and we can safely skip it. But it might
393                 // be there is a real software problem on our side.
394                 // This should be handlede more carefuly.
395                 debugOutput( DEBUG_LEVEL_NORMAL,
396                             "Could not read config rom from device (node id %d). "
397                             "Skip device discovering for this node\n",
398                             nodeId );
399                 continue;
400             }
401             configRoms.push_back(configRom);
402         }
403     }
404
405
406     // notify that we are going to manipulate the list
407     signalNotifiers(m_preUpdateNotifiers);
408     m_DeviceListLock->Lock(); // make sure nobody starts using the list
409     if(rediscover) {
410
411         FFADODeviceVector discovered_devices_on_bus;
412         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
413             it != m_avDevices.end();
414             ++it )
415         {
416             bool seen_device = false;
417             for ( ConfigRomVectorIterator it2 = configRoms.begin();
418                 it2 != configRoms.end();
419                 ++it2 )
420             {
421                 seen_device |= ((*it)->getConfigRom().getGuid() == (*it2)->getGuid());
422             }
423
424             if(seen_device) {
425                 debugOutput( DEBUG_LEVEL_VERBOSE,
426                             "Already discovered device with GUID: %s\n",
427                             (*it)->getConfigRom().getGuidString().c_str() );
428                 // we already discovered this device, and it is still here. keep it
429                 discovered_devices_on_bus.push_back(*it);
430             } else {
431                 debugOutput( DEBUG_LEVEL_VERBOSE,
432                             "Device with GUID: %s disappeared from bus, removing...\n",
433                             (*it)->getConfigRom().getGuidString().c_str() );
434
435                 // the device has disappeared, remove it from the control tree
436                 if (!deleteElement(*it)) {
437                     debugWarning("failed to remove Device from Control::Container\n");
438                 }
439                 // delete the device
440                 // FIXME: this will mess up the any code that waits for bus resets to
441                 //        occur
442                 delete *it;
443             }
444         }
445         // prune the devices that disappeared
446         m_avDevices = discovered_devices_on_bus;
447     } else { // remove everything since we are not rediscovering
448         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
449             it != m_avDevices.end();
450             ++it )
451         {
452             if (!deleteElement(*it)) {
453                 debugWarning("failed to remove Device from Control::Container\n");
454             }
455             delete *it;
456         }
457
458         m_avDevices.clear();
459     }
460
461     // delete the config rom list entries
462     // FIXME: we should reuse it
463     for ( ConfigRomVectorIterator it = configRoms.begin();
464         it != configRoms.end();
465         ++it )
466     {
467         delete *it;
468     }
469
470     assert(m_deviceStringParser);
471     // show the spec strings we're going to use
472     if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
473         m_deviceStringParser->show();
474     }
475
476     if (!slaveMode) {
477         // for the devices that are still in the list check if they require re-discovery
478         FFADODeviceVector failed_to_rediscover;
479         for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin();
480             it_dev != m_avDevices.end();
481             ++it_dev )
482         {
483             FFADODevice* avDevice = *it_dev;
484             if(avDevice->needsRediscovery()) {
485                 debugOutput( DEBUG_LEVEL_NORMAL,
486                              "Device with GUID %s requires rediscovery (state changed)...\n",
487                              avDevice->getConfigRom().getGuidString().c_str());
488
489                 bool isFromCache = false;
490                 if ( useCache && avDevice->loadFromCache() ) {
491                     debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
492                     isFromCache = true;
493                     // restore the debug level for everything that was loaded
494                     avDevice->setVerboseLevel( getDebugLevel() );
495                 } else if ( avDevice->discover() ) {
496                     debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
497                 } else {
498                     debugError( "could not discover device\n" );
499                     failed_to_rediscover.push_back(avDevice);
500                     continue;
501                 }
502                 if ( !isFromCache && !avDevice->saveCache() ) {
503                     debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
504                 }
505             } else {
506                 debugOutput( DEBUG_LEVEL_NORMAL,
507                              "Device with GUID %s does not require rediscovery...\n",
508                              avDevice->getConfigRom().getGuidString().c_str());
509             }
510         }
511         // remove devices that failed to rediscover
512         // FIXME: surely there has to be a better way to do this
513         FFADODeviceVector to_keep;
514         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
515             it != m_avDevices.end();
516             ++it )
517         {
518             bool keep_this_device = true;
519             for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin();
520                 it2 != failed_to_rediscover.end();
521                 ++it2 )
522             {
523                 if(*it == *it2) {
524                     debugOutput( DEBUG_LEVEL_NORMAL,
525                                 "Removing device with GUID %s due to failed discovery...\n",
526                                 (*it)->getConfigRom().getGuidString().c_str());
527                     keep_this_device = false;
528                     break;
529                 }
530             }
531             if(keep_this_device) {
532                 to_keep.push_back(*it);
533             }
534         }
535         for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin();
536             it2 != failed_to_rediscover.end();
537             ++it2 )
538         {
539             if (!deleteElement(*it2)) {
540                 debugWarning("failed to remove Device from Control::Container\n");
541             }
542             delete *it2;
543         }
544         m_avDevices = to_keep;
545
546         // pick up new devices
547         for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
548             it != m_1394Services.end();
549             ++it )
550         {
551             Ieee1394Service *portService = *it;
552             for ( fb_nodeid_t nodeId = 0;
553                 nodeId < portService->getNodeCount();
554                 ++nodeId )
555             {
556                 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
557    
558                 if (nodeId == portService->getLocalNodeId()) {
559                     debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
560                     continue;
561                 }
562    
563                 ConfigRom *configRom = new ConfigRom( *portService, nodeId );
564                 if ( !configRom->initialize() ) {
565                     // \todo If a PHY on the bus is in power safe mode then
566                     // the config rom is missing. So this might be just
567                     // such this case and we can safely skip it. But it might
568                     // be there is a real software problem on our side.
569                     // This should be handlede more carefuly.
570                     debugOutput( DEBUG_LEVEL_NORMAL,
571                                 "Could not read config rom from device (node id %d). "
572                                 "Skip device discovering for this node\n",
573                                 nodeId );
574                     continue;
575                 }
576
577                 bool already_in_vector = false;
578                 for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin();
579                     it_dev != m_avDevices.end();
580                     ++it_dev )
581                 {
582                     if ((*it_dev)->getConfigRom().getGuid() == configRom->getGuid()) {
583                         already_in_vector = true;
584                         break;
585                     }
586                 }
587                 if(already_in_vector) {
588                     if(!rediscover) {
589                         debugWarning("Device with GUID %s already discovered on other port, skipping device...\n",
590                                     configRom->getGuidString().c_str());
591                     }
592                     continue;
593                 }
594
595                 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
596                     configRom->printConfigRomDebug();
597                 }
598
599                 // if spec strings are given, only add those devices
600                 // that match the spec string(s).
601                 // if no (valid) spec strings are present, grab all
602                 // supported devices.
603                 if(m_deviceStringParser->countDeviceStrings() &&
604                   !m_deviceStringParser->match(*configRom)) {
605                     debugOutput(DEBUG_LEVEL_VERBOSE, "Device doesn't match any of the spec strings. skipping...\n");
606                     continue;
607                 }
608
609                 // find a driver
610                 FFADODevice* avDevice = getDriverForDevice( configRom,
611                                                             nodeId );
612
613                 if ( avDevice ) {
614                     debugOutput( DEBUG_LEVEL_NORMAL,
615                                 "driver found for device %d\n",
616                                 nodeId );
617
618                     avDevice->setVerboseLevel( getDebugLevel() );
619                     bool isFromCache = false;
620                     if ( useCache && avDevice->loadFromCache() ) {
621                         debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
622                         isFromCache = true;
623                         // restore the debug level for everything that was loaded
624                         avDevice->setVerboseLevel( getDebugLevel() );
625                     } else if ( avDevice->discover() ) {
626                         debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
627                     } else {
628                         debugError( "could not discover device\n" );
629                         delete avDevice;
630                         continue;
631                     }
632
633                     if (snoopMode) {
634                         debugOutput( DEBUG_LEVEL_VERBOSE,
635                                     "Enabling snoop mode on node %d...\n", nodeId );
636
637                         if(!avDevice->setOption("snoopMode", snoopMode)) {
638                             debugWarning("Could not set snoop mode for device on node %d\n", nodeId);
639                             delete avDevice;
640                             continue;
641                         }
642                     }
643
644                     if ( !isFromCache && !avDevice->saveCache() ) {
645                         debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
646                     }
647                     m_avDevices.push_back( avDevice );
648
649                     if (!addElement(avDevice)) {
650                         debugWarning("failed to add Device to Control::Container\n");
651                     }
652
653                     debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
654                 } else {
655                     // we didn't get a device, hence we have to delete the configrom ptr manually
656                     delete configRom;
657                 }
658             }
659         }
660
661         debugOutput( DEBUG_LEVEL_NORMAL, "Discovery finished...\n" );
662         // FIXME: do better sorting
663         // sort the m_avDevices vector on their GUID
664         // then assign reassign the id's to the devices
665         // the side effect of this is that for the same set of attached devices,
666         // a device id always corresponds to the same device
667         sort(m_avDevices.begin(), m_avDevices.end(), FFADODevice::compareGUID);
668
669         int i=0;
670         if(m_deviceStringParser->countDeviceStrings()) { // only if there are devicestrings
671             // first map the devices to a position using the device spec strings
672             std::map<fb_octlet_t, int> positionMap;
673             for ( FFADODeviceVectorIterator it = m_avDevices.begin();
674                 it != m_avDevices.end();
675                 ++it )
676             {
677                 int pos = m_deviceStringParser->matchPosition((*it)->getConfigRom());
678                 fb_octlet_t guid = (*it)->getConfigRom().getGuid();
679                 positionMap[guid] = pos;
680                 debugOutput( DEBUG_LEVEL_VERBOSE, "Mapping %s to position %d...\n", (*it)->getConfigRom().getGuidString().c_str(), pos );
681             }
682    
683             // now run over all positions, and add the devices that belong to it
684             FFADODeviceVector sorted;
685             int nbPositions = m_deviceStringParser->countDeviceStrings();
686             for (i=0; i < nbPositions; i++) {
687                 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
688                     it != m_avDevices.end();
689                     ++it )
690                 {
691                     fb_octlet_t guid = (*it)->getConfigRom().getGuid();
692                     if(positionMap[guid] == i) {
693                         sorted.push_back(*it);
694                     }
695                 }
696             }
697             // assign the new vector
698             flushDebugOutput();
699             assert(sorted.size() == m_avDevices.size());
700             m_avDevices = sorted;
701         }
702
703         showDeviceInfo();
704
705     } else { // slave mode
706         // notify any clients
707         signalNotifiers(m_preUpdateNotifiers);
708         Ieee1394Service *portService = m_1394Services.at(0);
709         fb_nodeid_t nodeId = portService->getLocalNodeId();
710         debugOutput( DEBUG_LEVEL_VERBOSE, "Starting in slave mode on node %d...\n", nodeId );
711
712         ffado_smartptr<ConfigRom> configRom =
713             ffado_smartptr<ConfigRom>( new ConfigRom( *portService,
714                                                      nodeId ) );
715         if ( !configRom->initialize() ) {
716             // \todo If a PHY on the bus is in power safe mode then
717             // the config rom is missing. So this might be just
718             // such this case and we can safely skip it. But it might
719             // be there is a real software problem on our side.
720             // This should be handled more carefuly.
721             debugOutput( DEBUG_LEVEL_NORMAL,
722                          "Could not read config rom from device (node id %d). "
723                          "Skip device discovering for this node\n",
724                          nodeId );
725             return false;
726         }
727
728         // remove any already present devices
729         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
730             it != m_avDevices.end();
731             ++it )
732         {
733             if (!deleteElement(*it)) {
734                 debugWarning("failed to remove Device from Control::Container\n");
735             }
736             delete *it;
737         }
738
739         m_avDevices.clear();
740
741         // get the slave driver
742         FFADODevice* avDevice = getSlaveDriver( configRom );
743         if ( avDevice ) {
744             debugOutput( DEBUG_LEVEL_NORMAL,
745                          "driver found for device %d\n",
746                          nodeId );
747
748             avDevice->setVerboseLevel( getDebugLevel() );
749
750             if ( !avDevice->discover() ) {
751                 debugError( "could not discover device\n" );
752                 delete avDevice;
753                 return false;
754             }
755
756             if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
757                 avDevice->showDevice();
758             }
759             m_avDevices.push_back( avDevice );
760             debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
761         }
762
763         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
764     }
765
766     m_DeviceListLock->Unlock();
767     // notify any clients
768     signalNotifiers(m_postUpdateNotifiers);
769     return true;
770 }
771
772 bool
773 DeviceManager::initStreaming()
774 {
775     // iterate over the found devices
776     // add the stream processors of the devices to the managers
777     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
778         it != m_avDevices.end();
779         ++it )
780     {
781         FFADODevice *device = *it;
782         assert(device);
783
784         debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device);
785
786         if (!device->lock()) {
787             debugWarning("Could not lock device, skipping device (%p)!\n", device);
788             continue;
789         }
790
791         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n",
792                     m_processorManager->getNominalRate(), device);
793
794         // Set the device's sampling rate to that requested
795         // FIXME: does this really belong here?  If so we need to handle errors.
796         if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
797             debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n",
798                         m_processorManager->getNominalRate(), device);
799
800             // try again:
801             if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
802                 debugFatal("Could not set sampling frequency to %d\n",m_processorManager->getNominalRate());
803                 return false;
804             }
805         }
806         // prepare the device
807         device->prepare();
808     }
809
810     // set the sync source
811     if (!m_processorManager->setSyncSource(getSyncSource())) {
812         debugWarning("Could not set processorManager sync source (%p)\n",
813             getSyncSource());
814     }
815
816     return true;
817 }
818
819 bool
820 DeviceManager::prepareStreaming()
821 {
822     if (!m_processorManager->prepare()) {
823         debugFatal("Could not prepare streaming...\n");
824         return false;
825     }
826     return true;
827 }
828
829 bool
830 DeviceManager::finishStreaming() {
831     bool result = true;
832     // iterate over the found devices
833     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
834         it != m_avDevices.end();
835         ++it )
836     {
837         debugOutput(DEBUG_LEVEL_VERBOSE, "Unlocking device (%p)\n", *it);
838
839         if (!(*it)->unlock()) {
840             debugWarning("Could not unlock device (%p)!\n", *it);
841             result = false;
842         }
843     }
844     return result;
845 }
846
847 bool
848 DeviceManager::startStreamingOnDevice(FFADODevice *device)
849 {
850     assert(device);
851
852     int j=0;
853     bool all_streams_started = true;
854     bool device_start_failed = false;
855
856     if (device->resetForStreaming() == false)
857         return false;
858
859     for(j=0; j < device->getStreamCount(); j++) {
860         debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %p\n", j, device);
861         // start the stream
862         if (!device->startStreamByIndex(j)) {
863             debugWarning("Could not start stream %d of device %p\n", j, device);
864             all_streams_started = false;
865             break;
866         }
867     }
868
869     if(!all_streams_started) {
870         // disable all streams that did start up correctly
871         for(j = j-1; j >= 0; j--) {
872             debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
873             // stop the stream
874             if (!device->stopStreamByIndex(j)) {
875                 debugWarning("Could not stop stream %d of device %p\n", j, device);
876             }
877         }
878         device_start_failed = true;
879     } else {
880         if (!device->enableStreaming()) {
881             debugWarning("Could not enable streaming on device %p!\n", device);
882             device_start_failed = true;
883         }
884     }
885     return !device_start_failed;
886 }
887
888 bool
889 DeviceManager::startStreaming() {
890     bool device_start_failed = false;
891     FFADODeviceVectorIterator it;
892
893     // create the connections for all devices
894     // iterate over the found devices
895     for ( it = m_avDevices.begin();
896         it != m_avDevices.end();
897         ++it )
898     {
899         if (!startStreamingOnDevice(*it)) {
900             debugWarning("Could not start streaming on device %p!\n", *it);
901             device_start_failed = true;
902             break;
903         }
904     }
905
906     // if one of the devices failed to start,
907     // the previous routine should have cleaned up the failing one.
908     // we still have to stop all devices that were started before this one.
909     if(device_start_failed) {
910         for (FFADODeviceVectorIterator it2 = m_avDevices.begin();
911             it2 != it;
912             ++it2 )
913         {
914             if (!stopStreamingOnDevice(*it2)) {
915                 debugWarning("Could not stop streaming on device %p!\n", *it2);
916             }
917         }
918         return false;
919     }
920
921     // start the stream processor manager to tune in to the channels
922     if(m_processorManager->start()) {
923         return true;
924     } else {
925         debugWarning("Failed to start SPM!\n");
926         for( it = m_avDevices.begin();
927              it != m_avDevices.end();
928              ++it )
929         {
930             if (!stopStreamingOnDevice(*it)) {
931                 debugWarning("Could not stop streaming on device %p!\n", *it);
932             }
933         }
934         return false;
935     }
936 }
937
938 bool
939 DeviceManager::resetStreaming() {
940     return true;
941 }
942
943 bool
944 DeviceManager::stopStreamingOnDevice(FFADODevice *device)
945 {
946     assert(device);
947     bool result = true;
948
949     if (!device->disableStreaming()) {
950         debugWarning("Could not disable streaming on device %p!\n", device);
951     }
952
953     int j=0;
954     for(j=0; j < device->getStreamCount(); j++) {
955         debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
956         // stop the stream
957         // start the stream
958         if (!device->stopStreamByIndex(j)) {
959             debugWarning("Could not stop stream %d of device %p\n", j, device);
960             result = false;
961             continue;
962         }
963     }
964     return result;
965 }
966
967 bool
968 DeviceManager::stopStreaming()
969 {
970     bool result = true;
971     m_processorManager->stop();
972
973     // create the connections for all devices
974     // iterate over the found devices
975     // add the stream processors of the devices to the managers
976     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
977         it != m_avDevices.end();
978         ++it )
979     {
980         stopStreamingOnDevice(*it);
981     }
982     return result;
983 }
984
985 enum DeviceManager::eWaitResult
986 DeviceManager::waitForPeriod() {
987     if(m_processorManager->waitForPeriod()) {
988         return eWR_OK;
989     } else {
990         if(m_processorManager->shutdownNeeded()) {
991             debugWarning("Shutdown requested\n");
992             return eWR_Shutdown;
993         } else {
994             debugWarning("XRUN detected\n");
995             // do xrun recovery
996             if(m_processorManager->handleXrun()) {
997                 return eWR_Xrun;
998             } else {
999                 debugError("Could not handle XRUN\n");
1000                 return eWR_Error;
1001             }
1002         }
1003     }
1004 }
1005
1006 bool
1007 DeviceManager::setPeriodSize(unsigned int period) {
1008     // Useful for cases where only the period size needs adjusting
1009     if (!m_processorManager->streamingParamsOk(period, -1, -1)) {
1010         return false;
1011     }
1012     m_processorManager->setPeriodSize(period);
1013     return true;
1014 }
1015
1016 bool
1017 DeviceManager::setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers) {
1018     if (!m_processorManager->streamingParamsOk(period, rate, nb_buffers)) {
1019         return false;
1020     }
1021     m_processorManager->setPeriodSize(period);
1022     m_processorManager->setNominalRate(rate);
1023     m_processorManager->setNbBuffers(nb_buffers);
1024     return true;
1025 }
1026
1027 FFADODevice*
1028 DeviceManager::getDriverForDeviceDo( ConfigRom *configRom,
1029                                    int id, bool generic )
1030 {
1031 #ifdef ENABLE_BEBOB
1032     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" );
1033     if ( BeBoB::Device::probe( getConfiguration(), *configRom, generic ) ) {
1034         return BeBoB::Device::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1035     }
1036 #endif
1037
1038 #ifdef ENABLE_FIREWORKS
1039     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying ECHO Audio FireWorks...\n" );
1040     if ( FireWorks::Device::probe( getConfiguration(), *configRom, generic ) ) {
1041         return FireWorks::Device::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1042     }
1043 #endif
1044
1045 #ifdef ENABLE_OXFORD
1046     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Oxford FW90x...\n" );
1047     if ( Oxford::Device::probe( getConfiguration(), *configRom, generic ) ) {
1048         return Oxford::Device::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1049     }
1050 #endif
1051
1052 // we want to try the non-generic AV/C platforms before trying the generic ones
1053 #ifdef ENABLE_GENERICAVC
1054     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" );
1055     if ( GenericAVC::Device::probe( getConfiguration(), *configRom, generic ) ) {
1056         return GenericAVC::Device::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1057     }
1058 #endif
1059
1060 #ifdef ENABLE_MOTU
1061     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" );
1062     if ( Motu::MotuDevice::probe( getConfiguration(), *configRom, generic ) ) {
1063         return Motu::MotuDevice::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1064     }
1065 #endif
1066
1067 #ifdef ENABLE_DICE
1068     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Dice...\n" );
1069     if ( Dice::Device::probe( getConfiguration(), *configRom, generic ) ) {
1070         return Dice::Device::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1071     }
1072 #endif
1073
1074 #ifdef ENABLE_METRIC_HALO
1075     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Metric Halo...\n" );
1076     if ( MetricHalo::Device::probe( getConfiguration(), *configRom, generic ) ) {
1077         return MetricHalo::Device::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1078     }
1079 #endif
1080
1081 #ifdef ENABLE_RME
1082     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying RME...\n" );
1083     if ( Rme::Device::probe( getConfiguration(), *configRom, generic ) ) {
1084         return Rme::Device::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1085     }
1086 #endif
1087
1088 #ifdef ENABLE_BOUNCE
1089     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Bounce...\n" );
1090     if ( Bounce::Device::probe( getConfiguration(), *configRom, generic ) ) {
1091         return Bounce::Device::createDevice( *this, ffado_smartptr<ConfigRom>( configRom ) );
1092     }
1093 #endif
1094
1095     return NULL;
1096 }
1097
1098 FFADODevice*
1099 DeviceManager::getDriverForDevice( ConfigRom *configRom,
1100                                    int id )
1101 {
1102     debugOutput( DEBUG_LEVEL_VERBOSE, "Probing for supported device...\n" );
1103     FFADODevice* dev = getDriverForDeviceDo(configRom, id, false);
1104     if(dev) {
1105         debugOutput( DEBUG_LEVEL_VERBOSE, " found supported device...\n" );
1106         dev->setVerboseLevel(getDebugLevel());
1107         return dev;
1108     }
1109
1110     debugOutput( DEBUG_LEVEL_VERBOSE, " no supported device found, trying generic support...\n" );
1111     dev = getDriverForDeviceDo(configRom, id, true);
1112     if(dev) {
1113         debugOutput( DEBUG_LEVEL_VERBOSE, " found generic support for device...\n" );
1114         dev->setVerboseLevel(getDebugLevel());
1115         return dev;
1116     }
1117     debugOutput( DEBUG_LEVEL_VERBOSE, " device not supported...\n" );
1118     return NULL;
1119 }
1120
1121 FFADODevice*
1122 DeviceManager::getSlaveDriver( ffado_smartptr<ConfigRom>( configRom ) )
1123 {
1124 #ifdef ENABLE_BOUNCE
1125     if ( Bounce::SlaveDevice::probe( getConfiguration(), *configRom, false ) ) {
1126         return Bounce::SlaveDevice::createDevice(  *this, ffado_smartptr<ConfigRom>( configRom ) );
1127     }
1128 #endif
1129     return NULL;
1130 }
1131
1132 bool
1133 DeviceManager::isValidNode(int node)
1134 {
1135     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1136           it != m_avDevices.end();
1137           ++it )
1138     {
1139         FFADODevice* avDevice = *it;
1140
1141         if (avDevice->getConfigRom().getNodeId() == node) {
1142             return true;
1143     }
1144     }
1145     return false;
1146 }
1147
1148 int
1149 DeviceManager::getNbDevices()
1150 {
1151     return m_avDevices.size();
1152 }
1153
1154 int
1155 DeviceManager::getDeviceNodeId( int deviceNr )
1156 {
1157     if ( ! ( deviceNr < getNbDevices() ) ) {
1158         debugError( "Device number out of range (%d)\n", deviceNr );
1159         return -1;
1160     }
1161
1162     FFADODevice* avDevice = m_avDevices.at( deviceNr );
1163
1164     if ( !avDevice ) {
1165         debugError( "Could not get device at position (%d)\n",  deviceNr );
1166     }
1167
1168     return avDevice->getConfigRom().getNodeId();
1169 }
1170
1171 FFADODevice*
1172 DeviceManager::getAvDevice( int nodeId )
1173 {
1174     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1175           it != m_avDevices.end();
1176           ++it )
1177     {
1178         FFADODevice* avDevice = *it;
1179         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
1180             return avDevice;
1181         }
1182     }
1183
1184     return 0;
1185 }
1186
1187 FFADODevice*
1188 DeviceManager::getAvDeviceByIndex( int idx )
1189 {
1190     return m_avDevices.at(idx);
1191 }
1192
1193 unsigned int
1194 DeviceManager::getAvDeviceCount( )
1195 {
1196     return m_avDevices.size();
1197 }
1198
1199 /**
1200  * Return the streamprocessor that is to be used as
1201  * the sync source.
1202  *
1203  * Algorithm still to be determined
1204  *
1205  * @return StreamProcessor that is sync source
1206  */
1207 Streaming::StreamProcessor *
1208 DeviceManager::getSyncSource() {
1209     FFADODevice* device = getAvDeviceByIndex(0);
1210
1211     bool slaveMode=false;
1212     if(!getOption("slaveMode", slaveMode)) {
1213         debugOutput(DEBUG_LEVEL_NORMAL,
1214                     "Could not retrieve slaveMode parameter, defauling to false\n");
1215     }
1216     return device->getStreamProcessorByIndex(0);
1217 /*
1218     #warning TEST CODE FOR BOUNCE DEVICE !!
1219     // this makes the bounce slave use the xmit SP as sync source
1220     if (slaveMode) {
1221         return device->getStreamProcessorByIndex(1);
1222     } else {
1223         return device->getStreamProcessorByIndex(0);
1224     }*/
1225 }
1226
1227 bool
1228 DeviceManager::deinitialize()
1229 {
1230     return true;
1231 }
1232
1233 void
1234 DeviceManager::setVerboseLevel(int l)
1235 {
1236     setDebugLevel(l);
1237     Control::Element::setVerboseLevel(l);
1238     m_processorManager->setVerboseLevel(l);
1239     m_deviceStringParser->setVerboseLevel(l);
1240     m_configuration->setVerboseLevel(l);
1241     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1242           it != m_avDevices.end();
1243           ++it )
1244     {
1245         (*it)->setVerboseLevel(l);
1246     }
1247     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
1248           it != m_1394Services.end();
1249           ++it )
1250     {
1251         (*it)->setVerboseLevel(l);
1252     }
1253     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
1254 }
1255
1256 void
1257 DeviceManager::showDeviceInfo() {
1258     debugOutput(DEBUG_LEVEL_NORMAL, "===== Device Manager =====\n");
1259     Control::Element::show();
1260
1261     int i=0;
1262     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
1263           it != m_1394Services.end();
1264           ++it )
1265     {
1266         debugOutput(DEBUG_LEVEL_NORMAL, "--- IEEE1394 Service %2d ---\n", i++);
1267         (*it)->show();
1268     }
1269
1270     i=0;
1271     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1272         it != m_avDevices.end();
1273         ++it )
1274     {
1275         FFADODevice* avDevice = *it;
1276         debugOutput(DEBUG_LEVEL_NORMAL, "--- Device %2d ---\n", i++);
1277         avDevice->showDevice();
1278
1279         debugOutput(DEBUG_LEVEL_NORMAL, "Clock sync sources:\n");
1280         FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources();
1281         for ( FFADODevice::ClockSourceVector::const_iterator it
1282                 = sources.begin();
1283             it != sources.end();
1284             ++it )
1285         {
1286             FFADODevice::ClockSource c=*it;
1287             debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %2d, Valid: %1d, Active: %1d, Locked %1d, Slipping: %1d, Description: %s\n",
1288                 FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.locked, c.slipping, c.description.c_str());
1289         }
1290     }
1291 }
1292 void
1293 DeviceManager::showStreamingInfo() {
1294     m_processorManager->dumpInfo();
1295 }
Note: See TracBrowser for help on using the browser.