dice: remove some prototype code which accidently made its way into r2416.
[ffado.git] / libffado / src / devicemanager.cpp
blob3ce82131aba7d34189c85efb8efd14350849842b
1 /*
2 * Copyright (C) 2005-2008 by Daniel Wagner
3 * Copyright (C) 2005-2008 by Pieter Palmers
5 * This file is part of FFADO
6 * FFADO = Free Firewire (pro-)audio drivers for linux
8 * FFADO is based upon FreeBoB.
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.
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.
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/>.
25 #include "config.h"
26 #include "fbtypes.h"
28 #include "devicemanager.h"
29 #include "ffadodevice.h"
30 #include "DeviceStringParser.h"
32 #include "libieee1394/configrom.h"
33 #include "libieee1394/ieee1394service.h"
34 #include "libieee1394/IsoHandlerManager.h"
36 #include "libstreaming/generic/StreamProcessor.h"
37 #include "libstreaming/StreamProcessorManager.h"
39 #include "debugmodule/debugmodule.h"
41 #include "libutil/PosixMutex.h"
43 #ifdef ENABLE_BEBOB
44 #include "bebob/bebob_avdevice.h"
45 #endif
47 #ifdef ENABLE_MAUDIO
48 #include "maudio/maudio_avdevice.h"
49 #endif
51 #ifdef ENABLE_GENERICAVC
52 #include "genericavc/avc_avdevice.h"
53 #endif
55 #ifdef ENABLE_FIREWORKS
56 #include "fireworks/fireworks_device.h"
57 #endif
59 #ifdef ENABLE_OXFORD
60 #include "oxford/oxford_device.h"
61 #endif
63 #ifdef ENABLE_BOUNCE
64 #include "bounce/bounce_avdevice.h"
65 #include "bounce/bounce_slave_avdevice.h"
66 #endif
68 #ifdef ENABLE_MOTU
69 #include "motu/motu_avdevice.h"
70 #endif
72 #ifdef ENABLE_RME
73 #include "rme/rme_avdevice.h"
74 #endif
76 #ifdef ENABLE_DICE
77 #include "dice/dice_avdevice.h"
78 #endif
80 #ifdef ENABLE_METRIC_HALO
81 #include "metrichalo/mh_avdevice.h"
82 #endif
84 #include <iostream>
85 #include <sstream>
87 #include <algorithm>
89 using namespace std;
91 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
93 DeviceManager::DeviceManager()
94 : Control::Container(NULL, "devicemanager") // this is the control root node
95 , m_DeviceListLock( new Util::PosixMutex("DEVLST") )
96 , m_BusResetLock( new Util::PosixMutex("DEVBR") )
97 , m_processorManager( new Streaming::StreamProcessorManager( *this ) )
98 , m_deviceStringParser( new DeviceStringParser() )
99 , m_configuration ( new Util::Configuration() )
100 , m_used_cache_last_time( false )
101 , m_thread_realtime( false )
102 , m_thread_priority( 0 )
104 addOption(Util::OptionContainer::Option("slaveMode", false));
105 addOption(Util::OptionContainer::Option("snoopMode", false));
108 DeviceManager::~DeviceManager()
110 // save configuration
111 if(!m_configuration->save()) {
112 debugWarning("could not save configuration\n");
115 m_BusResetLock->Lock(); // make sure we are not handling a busreset.
116 m_DeviceListLock->Lock(); // make sure nobody is using this
117 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
118 it != m_avDevices.end();
119 ++it )
121 if (!deleteElement(*it)) {
122 debugWarning("failed to remove Device from Control::Container\n");
124 delete *it;
126 m_DeviceListLock->Unlock();
128 // the SP's are automatically unregistered from the SPM
129 delete m_processorManager;
131 // the device list is empty, so wake up any waiting
132 // reset handlers
133 m_BusResetLock->Unlock();
135 // remove the bus-reset handlers
136 for ( FunctorVectorIterator it = m_busreset_functors.begin();
137 it != m_busreset_functors.end();
138 ++it )
140 delete *it;
143 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
144 it != m_1394Services.end();
145 ++it )
147 delete *it;
150 delete m_DeviceListLock;
151 delete m_BusResetLock;
152 delete m_deviceStringParser;
155 bool
156 DeviceManager::setThreadParameters(bool rt, int priority) {
157 if (!m_processorManager->setThreadParameters(rt, priority)) {
158 debugError("Could not set processor manager thread parameters\n");
159 return false;
161 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
162 it != m_1394Services.end();
163 ++it )
165 if (!(*it)->setThreadParameters(rt, priority)) {
166 debugError("Could not set 1394 service thread parameters\n");
167 return false;
170 m_thread_realtime = rt;
171 m_thread_priority = priority;
172 return true;
175 bool
176 DeviceManager::initialize()
178 assert(m_1394Services.size() == 0);
179 assert(m_busreset_functors.size() == 0);
181 m_configuration->openFile( "temporary", Util::Configuration::eFM_Temporary );
182 m_configuration->openFile( USER_CONFIG_FILE, Util::Configuration::eFM_ReadWrite );
183 m_configuration->openFile( SYSTEM_CONFIG_FILE, Util::Configuration::eFM_ReadOnly );
185 int nb_detected_ports = Ieee1394Service::detectNbPorts();
186 if (nb_detected_ports < 0) {
187 debugFatal("Failed to detect the number of 1394 adapters. Is the IEEE1394 stack loaded (raw1394)?\n");
188 return false;
190 if (nb_detected_ports == 0) {
191 debugFatal("No firewire adapters (ports) found.\n");
192 return false;
194 debugOutput( DEBUG_LEVEL_VERBOSE, "Found %d firewire adapters (ports)\n", nb_detected_ports);
195 for (unsigned int port = 0; port < (unsigned int)nb_detected_ports; port++) {
196 Ieee1394Service* tmp1394Service = new Ieee1394Service();
197 if ( !tmp1394Service ) {
198 debugFatal( "Could not create Ieee1349Service object for port %d\n", port );
199 return false;
201 tmp1394Service->setVerboseLevel( getDebugLevel() );
202 m_1394Services.push_back(tmp1394Service);
204 if(!tmp1394Service->useConfiguration(m_configuration)) {
205 debugWarning("Could not load config to 1394service\n");
208 tmp1394Service->setThreadParameters(m_thread_realtime, m_thread_priority);
209 if ( !tmp1394Service->initialize( port ) ) {
210 debugFatal( "Could not initialize Ieee1349Service object for port %d\n", port );
211 return false;
213 // add the bus reset handler
214 Util::Functor* tmp_busreset_functor = new Util::MemberFunctor1< DeviceManager*,
215 void (DeviceManager::*)(Ieee1394Service &), Ieee1394Service & >
216 ( this, &DeviceManager::busresetHandler, *tmp1394Service, false );
217 if ( !tmp_busreset_functor ) {
218 debugFatal( "Could not create busreset handler for port %d\n", port );
219 return false;
221 m_busreset_functors.push_back(tmp_busreset_functor);
223 tmp1394Service->addBusResetHandler( tmp_busreset_functor );
226 return true;
229 bool
230 DeviceManager::addSpecString(char *s) {
231 std::string spec = s;
232 if(isSpecStringValid(spec)) {
233 debugOutput(DEBUG_LEVEL_VERBOSE, "Adding spec string %s\n", spec.c_str());
234 assert(m_deviceStringParser);
235 m_deviceStringParser->parseString(spec);
236 return true;
237 } else {
238 debugError("Invalid spec string: %s\n", spec.c_str());
239 return false;
243 bool
244 DeviceManager::isSpecStringValid(std::string s) {
245 assert(m_deviceStringParser);
246 return m_deviceStringParser->isValidString(s);
249 void
250 DeviceManager::busresetHandler(Ieee1394Service &service)
252 // serialize bus reset handling since it can be that a new one occurs while we're
253 // doing stuff.
254 debugOutput( DEBUG_LEVEL_NORMAL, "Bus reset detected on service %p...\n", &service );
255 Util::MutexLockHelper lock(*m_BusResetLock);
256 debugOutput( DEBUG_LEVEL_NORMAL, " handling busreset...\n" );
258 // FIXME: what if the devices are gone? (device should detect this!)
259 // propagate the bus reset to all avDevices
260 m_DeviceListLock->Lock(); // make sure nobody is using this
261 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
262 it != m_avDevices.end();
263 ++it )
265 if(&service == &((*it)->get1394Service())) {
266 debugOutput(DEBUG_LEVEL_NORMAL,
267 "issue busreset on device GUID %s\n",
268 (*it)->getConfigRom().getGuidString().c_str());
269 (*it)->handleBusReset();
270 } else {
271 debugOutput(DEBUG_LEVEL_NORMAL,
272 "skipping device GUID %s since not on service %p\n",
273 (*it)->getConfigRom().getGuidString().c_str(), &service);
276 m_DeviceListLock->Unlock();
278 // now that the devices have been updates, we can request to update the iso streams
279 if(!service.getIsoHandlerManager().handleBusReset()) {
280 debugError("IsoHandlerManager failed to handle busreset\n");
283 // notify the streamprocessormanager of the busreset
284 // if(m_processorManager) {
285 // m_processorManager->handleBusReset(service);
286 // } else {
287 // debugWarning("No valid SPM\n");
288 // }
290 // rediscover to find new devices
291 // (only for the control server ATM, streaming can't dynamically add/remove devices)
292 if(!discover(m_used_cache_last_time, true)) {
293 debugError("Could not rediscover devices\n");
296 // notify any clients
297 signalNotifiers(m_busResetNotifiers);
299 // display the new state
300 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
301 showDeviceInfo();
305 void
306 DeviceManager::signalNotifiers(notif_vec_t& list)
308 for ( notif_vec_t::iterator it = list.begin();
309 it != list.end();
310 ++it )
312 Util::Functor* func = *it;
313 debugOutput( DEBUG_LEVEL_VERBOSE, " running notifier %p...\n", func );
314 ( *func )();
318 bool
319 DeviceManager::registerNotification(notif_vec_t& list, Util::Functor *handler)
321 debugOutput( DEBUG_LEVEL_VERBOSE, "register %p...\n", handler);
322 assert(handler);
323 for ( notif_vec_t::iterator it = list.begin();
324 it != list.end();
325 ++it )
327 if ( *it == handler ) {
328 debugOutput(DEBUG_LEVEL_VERBOSE, "already registered\n");
329 return false;
332 list.push_back(handler);
333 return true;
336 bool
337 DeviceManager::unregisterNotification(notif_vec_t& list, Util::Functor *handler)
339 debugOutput( DEBUG_LEVEL_VERBOSE, "unregister %p...\n", handler);
340 assert(handler);
342 for ( notif_vec_t::iterator it = list.begin();
343 it != list.end();
344 ++it )
346 if ( *it == handler ) {
347 list.erase(it);
348 return true;
351 debugError("Could not find handler (%p)\n", handler);
352 return false; //not found
355 bool
356 DeviceManager::discover( bool useCache, bool rediscover )
358 debugOutput( DEBUG_LEVEL_NORMAL, "Starting discovery...\n" );
359 useCache = useCache && ENABLE_DISCOVERY_CACHE;
360 m_used_cache_last_time = useCache;
361 bool slaveMode=false;
362 if(!getOption("slaveMode", slaveMode)) {
363 debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
365 bool snoopMode=false;
366 if(!getOption("snoopMode", snoopMode)) {
367 debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
370 setVerboseLevel(getDebugLevel());
372 // FIXME: it could be that a 1394service has disappeared (cardbus)
374 ConfigRomVector configRoms;
375 // build a list of configroms on the bus.
376 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
377 it != m_1394Services.end();
378 ++it )
380 Ieee1394Service *portService = *it;
381 for ( fb_nodeid_t nodeId = 0;
382 nodeId < portService->getNodeCount();
383 ++nodeId )
385 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
387 if (nodeId == portService->getLocalNodeId()) {
388 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
389 continue;
392 ConfigRom * configRom = new ConfigRom( *portService, nodeId );
393 if ( !configRom->initialize() ) {
394 // \todo If a PHY on the bus is in power safe mode then
395 // the config rom is missing. So this might be just
396 // such this case and we can safely skip it. But it might
397 // be there is a real software problem on our side.
398 // This should be handlede more carefuly.
399 debugOutput( DEBUG_LEVEL_NORMAL,
400 "Could not read config rom from device (node id %d). "
401 "Skip device discovering for this node\n",
402 nodeId );
403 continue;
405 configRoms.push_back(configRom);
410 // notify that we are going to manipulate the list
411 signalNotifiers(m_preUpdateNotifiers);
412 m_DeviceListLock->Lock(); // make sure nobody starts using the list
413 if(rediscover) {
415 FFADODeviceVector discovered_devices_on_bus;
416 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
417 it != m_avDevices.end();
418 ++it )
420 bool seen_device = false;
421 for ( ConfigRomVectorIterator it2 = configRoms.begin();
422 it2 != configRoms.end();
423 ++it2 )
425 seen_device |= ((*it)->getConfigRom().getGuid() == (*it2)->getGuid());
428 if(seen_device) {
429 debugOutput( DEBUG_LEVEL_VERBOSE,
430 "Already discovered device with GUID: %s\n",
431 (*it)->getConfigRom().getGuidString().c_str() );
432 // we already discovered this device, and it is still here. keep it
433 discovered_devices_on_bus.push_back(*it);
434 } else {
435 debugOutput( DEBUG_LEVEL_VERBOSE,
436 "Device with GUID: %s disappeared from bus, removing...\n",
437 (*it)->getConfigRom().getGuidString().c_str() );
439 // the device has disappeared, remove it from the control tree
440 if (!deleteElement(*it)) {
441 debugWarning("failed to remove Device from Control::Container\n");
443 // delete the device
444 // FIXME: this will mess up the any code that waits for bus resets to
445 // occur
446 delete *it;
449 // prune the devices that disappeared
450 m_avDevices = discovered_devices_on_bus;
451 } else { // remove everything since we are not rediscovering
452 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
453 it != m_avDevices.end();
454 ++it )
456 if (!deleteElement(*it)) {
457 debugWarning("failed to remove Device from Control::Container\n");
459 delete *it;
462 m_avDevices.clear();
465 // delete the config rom list entries
466 // FIXME: we should reuse it
467 for ( ConfigRomVectorIterator it = configRoms.begin();
468 it != configRoms.end();
469 ++it )
471 delete *it;
474 assert(m_deviceStringParser);
475 // show the spec strings we're going to use
476 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
477 m_deviceStringParser->show();
480 if (!slaveMode) {
481 // for the devices that are still in the list check if they require re-discovery
482 FFADODeviceVector failed_to_rediscover;
483 for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin();
484 it_dev != m_avDevices.end();
485 ++it_dev )
487 FFADODevice* avDevice = *it_dev;
488 if(avDevice->needsRediscovery()) {
489 debugOutput( DEBUG_LEVEL_NORMAL,
490 "Device with GUID %s requires rediscovery (state changed)...\n",
491 avDevice->getConfigRom().getGuidString().c_str());
493 bool isFromCache = false;
494 if ( useCache && avDevice->loadFromCache() ) {
495 debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
496 isFromCache = true;
497 // restore the debug level for everything that was loaded
498 avDevice->setVerboseLevel( getDebugLevel() );
499 } else if ( avDevice->discover() ) {
500 debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
501 } else {
502 debugError( "could not discover device\n" );
503 failed_to_rediscover.push_back(avDevice);
504 continue;
506 if ( !isFromCache && !avDevice->saveCache() ) {
507 debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
509 } else {
510 debugOutput( DEBUG_LEVEL_NORMAL,
511 "Device with GUID %s does not require rediscovery...\n",
512 avDevice->getConfigRom().getGuidString().c_str());
515 // remove devices that failed to rediscover
516 // FIXME: surely there has to be a better way to do this
517 FFADODeviceVector to_keep;
518 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
519 it != m_avDevices.end();
520 ++it )
522 bool keep_this_device = true;
523 for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin();
524 it2 != failed_to_rediscover.end();
525 ++it2 )
527 if(*it == *it2) {
528 debugOutput( DEBUG_LEVEL_NORMAL,
529 "Removing device with GUID %s due to failed discovery...\n",
530 (*it)->getConfigRom().getGuidString().c_str());
531 keep_this_device = false;
532 break;
535 if(keep_this_device) {
536 to_keep.push_back(*it);
539 for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin();
540 it2 != failed_to_rediscover.end();
541 ++it2 )
543 if (!deleteElement(*it2)) {
544 debugWarning("failed to remove Device from Control::Container\n");
546 delete *it2;
548 m_avDevices = to_keep;
550 // pick up new devices
551 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
552 it != m_1394Services.end();
553 ++it )
555 Ieee1394Service *portService = *it;
556 for ( fb_nodeid_t nodeId = 0;
557 nodeId < portService->getNodeCount();
558 ++nodeId )
560 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
562 if (nodeId == portService->getLocalNodeId()) {
563 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
564 continue;
567 ConfigRom *configRom = new ConfigRom( *portService, nodeId );
568 if ( !configRom->initialize() ) {
569 // \todo If a PHY on the bus is in power safe mode then
570 // the config rom is missing. So this might be just
571 // such this case and we can safely skip it. But it might
572 // be there is a real software problem on our side.
573 // This should be handlede more carefuly.
574 debugOutput( DEBUG_LEVEL_NORMAL,
575 "Could not read config rom from device (node id %d). "
576 "Skip device discovering for this node\n",
577 nodeId );
578 continue;
581 bool already_in_vector = false;
582 for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin();
583 it_dev != m_avDevices.end();
584 ++it_dev )
586 if ((*it_dev)->getConfigRom().getGuid() == configRom->getGuid()) {
587 already_in_vector = true;
588 break;
591 if(already_in_vector) {
592 if(!rediscover) {
593 debugWarning("Device with GUID %s already discovered on other port, skipping device...\n",
594 configRom->getGuidString().c_str());
596 continue;
599 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
600 configRom->printConfigRomDebug();
603 // if spec strings are given, only add those devices
604 // that match the spec string(s).
605 // if no (valid) spec strings are present, grab all
606 // supported devices.
607 if(m_deviceStringParser->countDeviceStrings() &&
608 !m_deviceStringParser->match(*configRom)) {
609 debugOutput(DEBUG_LEVEL_VERBOSE, "Device doesn't match any of the spec strings. skipping...\n");
610 continue;
613 // find a driver
614 FFADODevice* avDevice = getDriverForDevice( configRom,
615 nodeId );
617 if ( avDevice ) {
618 debugOutput( DEBUG_LEVEL_NORMAL,
619 "driver found for device %d\n",
620 nodeId );
622 avDevice->setVerboseLevel( getDebugLevel() );
623 bool isFromCache = false;
624 if ( useCache && avDevice->loadFromCache() ) {
625 debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
626 isFromCache = true;
627 // restore the debug level for everything that was loaded
628 avDevice->setVerboseLevel( getDebugLevel() );
629 } else if ( avDevice->discover() ) {
630 debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
631 } else {
632 debugError( "could not discover device\n" );
633 delete avDevice;
634 continue;
637 if (snoopMode) {
638 debugOutput( DEBUG_LEVEL_VERBOSE,
639 "Enabling snoop mode on node %d...\n", nodeId );
641 if(!avDevice->setOption("snoopMode", snoopMode)) {
642 debugWarning("Could not set snoop mode for device on node %d\n", nodeId);
643 delete avDevice;
644 continue;
648 if ( !isFromCache && !avDevice->saveCache() ) {
649 debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
651 m_avDevices.push_back( avDevice );
653 if (!addElement(avDevice)) {
654 debugWarning("failed to add Device to Control::Container\n");
657 debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
658 } else {
659 // we didn't get a device, hence we have to delete the configrom ptr manually
660 delete configRom;
665 debugOutput( DEBUG_LEVEL_NORMAL, "Discovery finished...\n" );
666 // FIXME: do better sorting
667 // sort the m_avDevices vector on their GUID
668 // then assign reassign the id's to the devices
669 // the side effect of this is that for the same set of attached devices,
670 // a device id always corresponds to the same device
671 sort(m_avDevices.begin(), m_avDevices.end(), FFADODevice::compareGUID);
673 int i=0;
674 if(m_deviceStringParser->countDeviceStrings()) { // only if there are devicestrings
675 // first map the devices to a position using the device spec strings
676 std::map<fb_octlet_t, int> positionMap;
677 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
678 it != m_avDevices.end();
679 ++it )
681 int pos = m_deviceStringParser->matchPosition((*it)->getConfigRom());
682 fb_octlet_t guid = (*it)->getConfigRom().getGuid();
683 positionMap[guid] = pos;
684 debugOutput( DEBUG_LEVEL_VERBOSE, "Mapping %s to position %d...\n", (*it)->getConfigRom().getGuidString().c_str(), pos );
687 // now run over all positions, and add the devices that belong to it
688 FFADODeviceVector sorted;
689 int nbPositions = m_deviceStringParser->countDeviceStrings();
690 for (i=0; i < nbPositions; i++) {
691 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
692 it != m_avDevices.end();
693 ++it )
695 fb_octlet_t guid = (*it)->getConfigRom().getGuid();
696 if(positionMap[guid] == i) {
697 sorted.push_back(*it);
701 // assign the new vector
702 flushDebugOutput();
703 assert(sorted.size() == m_avDevices.size());
704 m_avDevices = sorted;
707 showDeviceInfo();
709 } else { // slave mode
710 // notify any clients
711 signalNotifiers(m_preUpdateNotifiers);
712 Ieee1394Service *portService = m_1394Services.at(0);
713 fb_nodeid_t nodeId = portService->getLocalNodeId();
714 debugOutput( DEBUG_LEVEL_VERBOSE, "Starting in slave mode on node %d...\n", nodeId );
716 std::auto_ptr<ConfigRom> configRom =
717 std::auto_ptr<ConfigRom>( new ConfigRom( *portService,
718 nodeId ) );
719 if ( !configRom->initialize() ) {
720 // \todo If a PHY on the bus is in power safe mode then
721 // the config rom is missing. So this might be just
722 // such this case and we can safely skip it. But it might
723 // be there is a real software problem on our side.
724 // This should be handled more carefuly.
725 debugOutput( DEBUG_LEVEL_NORMAL,
726 "Could not read config rom from device (node id %d). "
727 "Skip device discovering for this node\n",
728 nodeId );
729 return false;
732 // remove any already present devices
733 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
734 it != m_avDevices.end();
735 ++it )
737 if (!deleteElement(*it)) {
738 debugWarning("failed to remove Device from Control::Container\n");
740 delete *it;
743 m_avDevices.clear();
745 // get the slave driver
746 FFADODevice* avDevice = getSlaveDriver( configRom );
747 if ( avDevice ) {
748 debugOutput( DEBUG_LEVEL_NORMAL,
749 "driver found for device %d\n",
750 nodeId );
752 avDevice->setVerboseLevel( getDebugLevel() );
754 if ( !avDevice->discover() ) {
755 debugError( "could not discover device\n" );
756 delete avDevice;
757 return false;
760 if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
761 avDevice->showDevice();
763 m_avDevices.push_back( avDevice );
764 debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
767 debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
770 m_DeviceListLock->Unlock();
771 // notify any clients
772 signalNotifiers(m_postUpdateNotifiers);
773 return true;
776 bool
777 DeviceManager::initStreaming()
779 // iterate over the found devices
780 // add the stream processors of the devices to the managers
781 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
782 it != m_avDevices.end();
783 ++it )
785 FFADODevice *device = *it;
786 assert(device);
788 debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device);
790 if (!device->lock()) {
791 debugWarning("Could not lock device, skipping device (%p)!\n", device);
792 continue;
795 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n",
796 m_processorManager->getNominalRate(), device);
798 // Set the device's sampling rate to that requested
799 // FIXME: does this really belong here? If so we need to handle errors.
800 if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
801 debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n",
802 m_processorManager->getNominalRate(), device);
804 // try again:
805 if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
806 debugFatal("Could not set sampling frequency to %d\n",m_processorManager->getNominalRate());
807 return false;
810 // prepare the device
811 device->prepare();
814 // set the sync source
815 if (!m_processorManager->setSyncSource(getSyncSource())) {
816 debugWarning("Could not set processorManager sync source (%p)\n",
817 getSyncSource());
820 return true;
823 bool
824 DeviceManager::prepareStreaming()
826 if (!m_processorManager->prepare()) {
827 debugFatal("Could not prepare streaming...\n");
828 return false;
830 return true;
833 bool
834 DeviceManager::finishStreaming() {
835 bool result = true;
836 // iterate over the found devices
837 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
838 it != m_avDevices.end();
839 ++it )
841 debugOutput(DEBUG_LEVEL_VERBOSE, "Unlocking device (%p)\n", *it);
843 if (!(*it)->unlock()) {
844 debugWarning("Could not unlock device (%p)!\n", *it);
845 result = false;
848 return result;
851 bool
852 DeviceManager::startStreamingOnDevice(FFADODevice *device)
854 assert(device);
856 int j=0;
857 bool all_streams_started = true;
858 bool device_start_failed = false;
860 if (device->resetForStreaming() == false)
861 return false;
863 for(j=0; j < device->getStreamCount(); j++) {
864 debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %p\n", j, device);
865 // start the stream
866 if (!device->startStreamByIndex(j)) {
867 debugWarning("Could not start stream %d of device %p\n", j, device);
868 all_streams_started = false;
869 break;
873 if(!all_streams_started) {
874 // disable all streams that did start up correctly
875 for(j = j-1; j >= 0; j--) {
876 debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
877 // stop the stream
878 if (!device->stopStreamByIndex(j)) {
879 debugWarning("Could not stop stream %d of device %p\n", j, device);
882 device_start_failed = true;
883 } else {
884 if (!device->enableStreaming()) {
885 debugWarning("Could not enable streaming on device %p!\n", device);
886 device_start_failed = true;
889 return !device_start_failed;
892 bool
893 DeviceManager::startStreaming() {
894 bool device_start_failed = false;
895 FFADODeviceVectorIterator it;
897 // create the connections for all devices
898 // iterate over the found devices
899 for ( it = m_avDevices.begin();
900 it != m_avDevices.end();
901 ++it )
903 if (!startStreamingOnDevice(*it)) {
904 debugWarning("Could not start streaming on device %p!\n", *it);
905 device_start_failed = true;
906 break;
910 // if one of the devices failed to start,
911 // the previous routine should have cleaned up the failing one.
912 // we still have to stop all devices that were started before this one.
913 if(device_start_failed) {
914 for (FFADODeviceVectorIterator it2 = m_avDevices.begin();
915 it2 != it;
916 ++it2 )
918 if (!stopStreamingOnDevice(*it2)) {
919 debugWarning("Could not stop streaming on device %p!\n", *it2);
922 return false;
925 // start the stream processor manager to tune in to the channels
926 if(m_processorManager->start()) {
927 return true;
928 } else {
929 debugWarning("Failed to start SPM!\n");
930 for( it = m_avDevices.begin();
931 it != m_avDevices.end();
932 ++it )
934 if (!stopStreamingOnDevice(*it)) {
935 debugWarning("Could not stop streaming on device %p!\n", *it);
938 return false;
942 bool
943 DeviceManager::resetStreaming() {
944 return true;
947 bool
948 DeviceManager::stopStreamingOnDevice(FFADODevice *device)
950 assert(device);
951 bool result = true;
953 if (!device->disableStreaming()) {
954 debugWarning("Could not disable streaming on device %p!\n", device);
957 int j=0;
958 for(j=0; j < device->getStreamCount(); j++) {
959 debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
960 // stop the stream
961 // start the stream
962 if (!device->stopStreamByIndex(j)) {
963 debugWarning("Could not stop stream %d of device %p\n", j, device);
964 result = false;
965 continue;
968 return result;
971 bool
972 DeviceManager::stopStreaming()
974 bool result = true;
975 m_processorManager->stop();
977 // create the connections for all devices
978 // iterate over the found devices
979 // add the stream processors of the devices to the managers
980 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
981 it != m_avDevices.end();
982 ++it )
984 stopStreamingOnDevice(*it);
986 return result;
989 enum DeviceManager::eWaitResult
990 DeviceManager::waitForPeriod() {
991 if(m_processorManager->waitForPeriod()) {
992 return eWR_OK;
993 } else {
994 if(m_processorManager->shutdownNeeded()) {
995 debugWarning("Shutdown requested\n");
996 return eWR_Shutdown;
997 } else {
998 debugWarning("XRUN detected\n");
999 // do xrun recovery
1000 if(m_processorManager->handleXrun()) {
1001 return eWR_Xrun;
1002 } else {
1003 debugError("Could not handle XRUN\n");
1004 return eWR_Error;
1010 bool
1011 DeviceManager::setPeriodSize(unsigned int period) {
1012 // Useful for cases where only the period size needs adjusting
1013 if (!m_processorManager->streamingParamsOk(period, -1, -1)) {
1014 return false;
1016 m_processorManager->setPeriodSize(period);
1017 return true;
1020 bool
1021 DeviceManager::setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers) {
1022 if (!m_processorManager->streamingParamsOk(period, rate, nb_buffers)) {
1023 return false;
1025 m_processorManager->setPeriodSize(period);
1026 m_processorManager->setNominalRate(rate);
1027 m_processorManager->setNbBuffers(nb_buffers);
1028 return true;
1031 FFADODevice*
1032 DeviceManager::getDriverForDeviceDo( ConfigRom *configRom,
1033 int id, bool generic )
1035 #ifdef ENABLE_BEBOB
1036 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" );
1037 if ( BeBoB::Device::probe( getConfiguration(), *configRom, generic ) ) {
1038 return BeBoB::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1040 #endif
1042 #ifdef ENABLE_FIREWORKS
1043 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying ECHO Audio FireWorks...\n" );
1044 if ( FireWorks::Device::probe( getConfiguration(), *configRom, generic ) ) {
1045 return FireWorks::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1047 #endif
1049 #ifdef ENABLE_OXFORD
1050 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Oxford FW90x...\n" );
1051 if ( Oxford::Device::probe( getConfiguration(), *configRom, generic ) ) {
1052 return Oxford::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1054 #endif
1056 #ifdef ENABLE_MAUDIO
1057 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying M-Audio...\n" );
1058 if ( MAudio::Device::probe( getConfiguration(), *configRom, generic ) ) {
1059 return MAudio::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1061 #endif
1063 // we want to try the non-generic AV/C platforms before trying the generic ones
1064 #ifdef ENABLE_GENERICAVC
1065 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" );
1066 if ( GenericAVC::Device::probe( getConfiguration(), *configRom, generic ) ) {
1067 return GenericAVC::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1069 #endif
1071 #ifdef ENABLE_MOTU
1072 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" );
1073 if ( Motu::MotuDevice::probe( getConfiguration(), *configRom, generic ) ) {
1074 return Motu::MotuDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1076 #endif
1078 #ifdef ENABLE_DICE
1079 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Dice...\n" );
1080 if ( Dice::Device::probe( getConfiguration(), *configRom, generic ) ) {
1081 return Dice::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1083 #endif
1085 #ifdef ENABLE_METRIC_HALO
1086 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Metric Halo...\n" );
1087 if ( MetricHalo::Device::probe( getConfiguration(), *configRom, generic ) ) {
1088 return MetricHalo::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1090 #endif
1092 #ifdef ENABLE_RME
1093 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying RME...\n" );
1094 if ( Rme::Device::probe( getConfiguration(), *configRom, generic ) ) {
1095 return Rme::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1097 #endif
1099 #ifdef ENABLE_BOUNCE
1100 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Bounce...\n" );
1101 if ( Bounce::Device::probe( getConfiguration(), *configRom, generic ) ) {
1102 return Bounce::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1104 #endif
1106 return NULL;
1109 FFADODevice*
1110 DeviceManager::getDriverForDevice( ConfigRom *configRom,
1111 int id )
1113 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing for supported device...\n" );
1114 FFADODevice* dev = getDriverForDeviceDo(configRom, id, false);
1115 if(dev) {
1116 debugOutput( DEBUG_LEVEL_VERBOSE, " found supported device...\n" );
1117 dev->setVerboseLevel(getDebugLevel());
1118 return dev;
1121 debugOutput( DEBUG_LEVEL_VERBOSE, " no supported device found, trying generic support...\n" );
1122 dev = getDriverForDeviceDo(configRom, id, true);
1123 if(dev) {
1124 debugOutput( DEBUG_LEVEL_VERBOSE, " found generic support for device...\n" );
1125 dev->setVerboseLevel(getDebugLevel());
1126 return dev;
1128 debugOutput( DEBUG_LEVEL_VERBOSE, " device not supported...\n" );
1129 return NULL;
1132 FFADODevice*
1133 DeviceManager::getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) )
1135 #ifdef ENABLE_BOUNCE
1136 if ( Bounce::SlaveDevice::probe( getConfiguration(), *configRom, false ) ) {
1137 return Bounce::SlaveDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1139 #endif
1140 return NULL;
1143 bool
1144 DeviceManager::isValidNode(int node)
1146 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1147 it != m_avDevices.end();
1148 ++it )
1150 FFADODevice* avDevice = *it;
1152 if (avDevice->getConfigRom().getNodeId() == node) {
1153 return true;
1156 return false;
1160 DeviceManager::getNbDevices()
1162 return m_avDevices.size();
1166 DeviceManager::getDeviceNodeId( int deviceNr )
1168 if ( ! ( deviceNr < getNbDevices() ) ) {
1169 debugError( "Device number out of range (%d)\n", deviceNr );
1170 return -1;
1173 FFADODevice* avDevice = m_avDevices.at( deviceNr );
1175 if ( !avDevice ) {
1176 debugError( "Could not get device at position (%d)\n", deviceNr );
1179 return avDevice->getConfigRom().getNodeId();
1182 FFADODevice*
1183 DeviceManager::getAvDevice( int nodeId )
1185 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1186 it != m_avDevices.end();
1187 ++it )
1189 FFADODevice* avDevice = *it;
1190 if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
1191 return avDevice;
1195 return 0;
1198 FFADODevice*
1199 DeviceManager::getAvDeviceByIndex( int idx )
1201 return m_avDevices.at(idx);
1204 unsigned int
1205 DeviceManager::getAvDeviceCount( )
1207 return m_avDevices.size();
1211 * Return the streamprocessor that is to be used as
1212 * the sync source.
1214 * Algorithm still to be determined
1216 * @return StreamProcessor that is sync source
1218 Streaming::StreamProcessor *
1219 DeviceManager::getSyncSource() {
1220 FFADODevice* device = getAvDeviceByIndex(0);
1222 bool slaveMode=false;
1223 if(!getOption("slaveMode", slaveMode)) {
1224 debugOutput(DEBUG_LEVEL_NORMAL,
1225 "Could not retrieve slaveMode parameter, defauling to false\n");
1227 return device->getStreamProcessorByIndex(0);
1229 #warning TEST CODE FOR BOUNCE DEVICE !!
1230 // this makes the bounce slave use the xmit SP as sync source
1231 if (slaveMode) {
1232 return device->getStreamProcessorByIndex(1);
1233 } else {
1234 return device->getStreamProcessorByIndex(0);
1238 bool
1239 DeviceManager::deinitialize()
1241 return true;
1244 void
1245 DeviceManager::setVerboseLevel(int l)
1247 setDebugLevel(l);
1248 Control::Element::setVerboseLevel(l);
1249 m_processorManager->setVerboseLevel(l);
1250 m_deviceStringParser->setVerboseLevel(l);
1251 m_configuration->setVerboseLevel(l);
1252 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1253 it != m_avDevices.end();
1254 ++it )
1256 (*it)->setVerboseLevel(l);
1258 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
1259 it != m_1394Services.end();
1260 ++it )
1262 (*it)->setVerboseLevel(l);
1264 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
1267 void
1268 DeviceManager::showDeviceInfo() {
1269 debugOutput(DEBUG_LEVEL_NORMAL, "===== Device Manager =====\n");
1270 Control::Element::show();
1272 int i=0;
1273 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
1274 it != m_1394Services.end();
1275 ++it )
1277 debugOutput(DEBUG_LEVEL_NORMAL, "--- IEEE1394 Service %2d ---\n", i++);
1278 (*it)->show();
1281 i=0;
1282 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1283 it != m_avDevices.end();
1284 ++it )
1286 FFADODevice* avDevice = *it;
1287 debugOutput(DEBUG_LEVEL_NORMAL, "--- Device %2d ---\n", i++);
1288 avDevice->showDevice();
1290 debugOutput(DEBUG_LEVEL_NORMAL, "Clock sync sources:\n");
1291 FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources();
1292 for ( FFADODevice::ClockSourceVector::const_iterator it
1293 = sources.begin();
1294 it != sources.end();
1295 ++it )
1297 FFADODevice::ClockSource c=*it;
1298 debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %2d, Valid: %1d, Active: %1d, Locked %1d, Slipping: %1d, Description: %s\n",
1299 FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.locked, c.slipping, c.description.c_str());
1303 void
1304 DeviceManager::showStreamingInfo() {
1305 m_processorManager->dumpInfo();