motu: the 4pre channel layout within packets is now believed to be correct. Thanks...
[ffado.git] / libffado / src / devicemanager.cpp
blob79ef2abbbbf8bc99df6018d4bdb4416cca2ae5c3
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_GENERICAVC
48 #include "genericavc/avc_avdevice.h"
49 #endif
51 #ifdef ENABLE_FIREWORKS
52 #include "fireworks/fireworks_device.h"
53 #endif
55 #ifdef ENABLE_OXFORD
56 #include "oxford/oxford_device.h"
57 #endif
59 #ifdef ENABLE_BOUNCE
60 #include "bounce/bounce_avdevice.h"
61 #include "bounce/bounce_slave_avdevice.h"
62 #endif
64 #ifdef ENABLE_MOTU
65 #include "motu/motu_avdevice.h"
66 #endif
68 #ifdef ENABLE_RME
69 #include "rme/rme_avdevice.h"
70 #endif
72 #ifdef ENABLE_DICE
73 #include "dice/dice_avdevice.h"
74 #endif
76 #ifdef ENABLE_METRIC_HALO
77 #include "metrichalo/mh_avdevice.h"
78 #endif
80 #include <iostream>
81 #include <sstream>
83 #include <algorithm>
85 using namespace std;
87 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
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 )
100 addOption(Util::OptionContainer::Option("slaveMode", false));
101 addOption(Util::OptionContainer::Option("snoopMode", false));
104 DeviceManager::~DeviceManager()
106 // save configuration
107 if(!m_configuration->save()) {
108 debugWarning("could not save configuration\n");
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 )
117 if (!deleteElement(*it)) {
118 debugWarning("failed to remove Device from Control::Container\n");
120 delete *it;
122 m_DeviceListLock->Unlock();
124 // the SP's are automatically unregistered from the SPM
125 delete m_processorManager;
127 // the device list is empty, so wake up any waiting
128 // reset handlers
129 m_BusResetLock->Unlock();
131 // remove the bus-reset handlers
132 for ( FunctorVectorIterator it = m_busreset_functors.begin();
133 it != m_busreset_functors.end();
134 ++it )
136 delete *it;
139 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
140 it != m_1394Services.end();
141 ++it )
143 delete *it;
146 delete m_DeviceListLock;
147 delete m_BusResetLock;
148 delete m_deviceStringParser;
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;
157 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
158 it != m_1394Services.end();
159 ++it )
161 if (!(*it)->setThreadParameters(rt, priority)) {
162 debugError("Could not set 1394 service thread parameters\n");
163 return false;
166 m_thread_realtime = rt;
167 m_thread_priority = priority;
168 return true;
171 bool
172 DeviceManager::initialize()
174 assert(m_1394Services.size() == 0);
175 assert(m_busreset_functors.size() == 0);
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 );
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;
186 if (nb_detected_ports == 0) {
187 debugFatal("No firewire adapters (ports) found.\n");
188 return false;
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;
197 tmp1394Service->setVerboseLevel( getDebugLevel() );
198 m_1394Services.push_back(tmp1394Service);
200 if(!tmp1394Service->useConfiguration(m_configuration)) {
201 debugWarning("Could not load config to 1394service\n");
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;
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;
217 m_busreset_functors.push_back(tmp_busreset_functor);
219 tmp1394Service->addBusResetHandler( tmp_busreset_functor );
222 return true;
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;
239 bool
240 DeviceManager::isSpecStringValid(std::string s) {
241 assert(m_deviceStringParser);
242 return m_deviceStringParser->isValidString(s);
245 void
246 DeviceManager::busresetHandler(Ieee1394Service &service)
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" );
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 )
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);
272 m_DeviceListLock->Unlock();
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");
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 // }
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");
292 // notify any clients
293 signalNotifiers(m_busResetNotifiers);
295 // display the new state
296 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
297 showDeviceInfo();
301 void
302 DeviceManager::signalNotifiers(notif_vec_t& list)
304 for ( notif_vec_t::iterator it = list.begin();
305 it != list.end();
306 ++it )
308 Util::Functor* func = *it;
309 debugOutput( DEBUG_LEVEL_VERBOSE, " running notifier %p...\n", func );
310 ( *func )();
314 bool
315 DeviceManager::registerNotification(notif_vec_t& list, Util::Functor *handler)
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 )
323 if ( *it == handler ) {
324 debugOutput(DEBUG_LEVEL_VERBOSE, "already registered\n");
325 return false;
328 list.push_back(handler);
329 return true;
332 bool
333 DeviceManager::unregisterNotification(notif_vec_t& list, Util::Functor *handler)
335 debugOutput( DEBUG_LEVEL_VERBOSE, "unregister %p...\n", handler);
336 assert(handler);
338 for ( notif_vec_t::iterator it = list.begin();
339 it != list.end();
340 ++it )
342 if ( *it == handler ) {
343 list.erase(it);
344 return true;
347 debugError("Could not find handler (%p)\n", handler);
348 return false; //not found
351 bool
352 DeviceManager::discover( bool useCache, bool rediscover )
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");
361 bool snoopMode=false;
362 if(!getOption("snoopMode", snoopMode)) {
363 debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
366 setVerboseLevel(getDebugLevel());
368 // FIXME: it could be that a 1394service has disappeared (cardbus)
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 )
376 Ieee1394Service *portService = *it;
377 for ( fb_nodeid_t nodeId = 0;
378 nodeId < portService->getNodeCount();
379 ++nodeId )
381 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
383 if (nodeId == portService->getLocalNodeId()) {
384 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
385 continue;
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;
401 configRoms.push_back(configRom);
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) {
411 FFADODeviceVector discovered_devices_on_bus;
412 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
413 it != m_avDevices.end();
414 ++it )
416 bool seen_device = false;
417 for ( ConfigRomVectorIterator it2 = configRoms.begin();
418 it2 != configRoms.end();
419 ++it2 )
421 seen_device |= ((*it)->getConfigRom().getGuid() == (*it2)->getGuid());
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() );
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");
439 // delete the device
440 // FIXME: this will mess up the any code that waits for bus resets to
441 // occur
442 delete *it;
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 )
452 if (!deleteElement(*it)) {
453 debugWarning("failed to remove Device from Control::Container\n");
455 delete *it;
458 m_avDevices.clear();
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 )
467 delete *it;
470 assert(m_deviceStringParser);
471 // show the spec strings we're going to use
472 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
473 m_deviceStringParser->show();
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 )
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());
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;
502 if ( !isFromCache && !avDevice->saveCache() ) {
503 debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
505 } else {
506 debugOutput( DEBUG_LEVEL_NORMAL,
507 "Device with GUID %s does not require rediscovery...\n",
508 avDevice->getConfigRom().getGuidString().c_str());
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 )
518 bool keep_this_device = true;
519 for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin();
520 it2 != failed_to_rediscover.end();
521 ++it2 )
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;
531 if(keep_this_device) {
532 to_keep.push_back(*it);
535 for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin();
536 it2 != failed_to_rediscover.end();
537 ++it2 )
539 if (!deleteElement(*it2)) {
540 debugWarning("failed to remove Device from Control::Container\n");
542 delete *it2;
544 m_avDevices = to_keep;
546 // pick up new devices
547 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
548 it != m_1394Services.end();
549 ++it )
551 Ieee1394Service *portService = *it;
552 for ( fb_nodeid_t nodeId = 0;
553 nodeId < portService->getNodeCount();
554 ++nodeId )
556 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
558 if (nodeId == portService->getLocalNodeId()) {
559 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
560 continue;
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;
577 bool already_in_vector = false;
578 for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin();
579 it_dev != m_avDevices.end();
580 ++it_dev )
582 if ((*it_dev)->getConfigRom().getGuid() == configRom->getGuid()) {
583 already_in_vector = true;
584 break;
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());
592 continue;
595 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
596 configRom->printConfigRomDebug();
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;
609 // find a driver
610 FFADODevice* avDevice = getDriverForDevice( configRom,
611 nodeId );
613 if ( avDevice ) {
614 debugOutput( DEBUG_LEVEL_NORMAL,
615 "driver found for device %d\n",
616 nodeId );
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;
633 if (snoopMode) {
634 debugOutput( DEBUG_LEVEL_VERBOSE,
635 "Enabling snoop mode on node %d...\n", nodeId );
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;
644 if ( !isFromCache && !avDevice->saveCache() ) {
645 debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
647 m_avDevices.push_back( avDevice );
649 if (!addElement(avDevice)) {
650 debugWarning("failed to add Device to Control::Container\n");
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;
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);
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 )
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 );
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 )
691 fb_octlet_t guid = (*it)->getConfigRom().getGuid();
692 if(positionMap[guid] == i) {
693 sorted.push_back(*it);
697 // assign the new vector
698 flushDebugOutput();
699 assert(sorted.size() == m_avDevices.size());
700 m_avDevices = sorted;
703 showDeviceInfo();
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 );
712 std::auto_ptr<ConfigRom> configRom =
713 std::auto_ptr<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;
728 // remove any already present devices
729 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
730 it != m_avDevices.end();
731 ++it )
733 if (!deleteElement(*it)) {
734 debugWarning("failed to remove Device from Control::Container\n");
736 delete *it;
739 m_avDevices.clear();
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 );
748 avDevice->setVerboseLevel( getDebugLevel() );
750 if ( !avDevice->discover() ) {
751 debugError( "could not discover device\n" );
752 delete avDevice;
753 return false;
756 if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
757 avDevice->showDevice();
759 m_avDevices.push_back( avDevice );
760 debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
763 debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
766 m_DeviceListLock->Unlock();
767 // notify any clients
768 signalNotifiers(m_postUpdateNotifiers);
769 return true;
772 bool
773 DeviceManager::initStreaming()
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 )
781 FFADODevice *device = *it;
782 assert(device);
784 debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device);
786 if (!device->lock()) {
787 debugWarning("Could not lock device, skipping device (%p)!\n", device);
788 continue;
791 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n",
792 m_processorManager->getNominalRate(), device);
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);
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;
806 // prepare the device
807 device->prepare();
810 // set the sync source
811 if (!m_processorManager->setSyncSource(getSyncSource())) {
812 debugWarning("Could not set processorManager sync source (%p)\n",
813 getSyncSource());
816 return true;
819 bool
820 DeviceManager::prepareStreaming()
822 if (!m_processorManager->prepare()) {
823 debugFatal("Could not prepare streaming...\n");
824 return false;
826 return true;
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 )
837 debugOutput(DEBUG_LEVEL_VERBOSE, "Unlocking device (%p)\n", *it);
839 if (!(*it)->unlock()) {
840 debugWarning("Could not unlock device (%p)!\n", *it);
841 result = false;
844 return result;
847 bool
848 DeviceManager::startStreamingOnDevice(FFADODevice *device)
850 assert(device);
852 int j=0;
853 bool all_streams_started = true;
854 bool device_start_failed = false;
856 if (device->resetForStreaming() == false)
857 return false;
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;
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);
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;
885 return !device_start_failed;
888 bool
889 DeviceManager::startStreaming() {
890 bool device_start_failed = false;
891 FFADODeviceVectorIterator it;
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 )
899 if (!startStreamingOnDevice(*it)) {
900 debugWarning("Could not start streaming on device %p!\n", *it);
901 device_start_failed = true;
902 break;
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 )
914 if (!stopStreamingOnDevice(*it2)) {
915 debugWarning("Could not stop streaming on device %p!\n", *it2);
918 return false;
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 )
930 if (!stopStreamingOnDevice(*it)) {
931 debugWarning("Could not stop streaming on device %p!\n", *it);
934 return false;
938 bool
939 DeviceManager::resetStreaming() {
940 return true;
943 bool
944 DeviceManager::stopStreamingOnDevice(FFADODevice *device)
946 assert(device);
947 bool result = true;
949 if (!device->disableStreaming()) {
950 debugWarning("Could not disable streaming on device %p!\n", device);
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;
964 return result;
967 bool
968 DeviceManager::stopStreaming()
970 bool result = true;
971 m_processorManager->stop();
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 )
980 stopStreamingOnDevice(*it);
982 return result;
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;
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;
1012 m_processorManager->setPeriodSize(period);
1013 return true;
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;
1021 m_processorManager->setPeriodSize(period);
1022 m_processorManager->setNominalRate(rate);
1023 m_processorManager->setNbBuffers(nb_buffers);
1024 return true;
1027 FFADODevice*
1028 DeviceManager::getDriverForDeviceDo( ConfigRom *configRom,
1029 int id, bool generic )
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, std::auto_ptr<ConfigRom>( configRom ) );
1036 #endif
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, std::auto_ptr<ConfigRom>( configRom ) );
1043 #endif
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, std::auto_ptr<ConfigRom>( configRom ) );
1050 #endif
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, std::auto_ptr<ConfigRom>( configRom ) );
1058 #endif
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, std::auto_ptr<ConfigRom>( configRom ) );
1065 #endif
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, std::auto_ptr<ConfigRom>( configRom ) );
1072 #endif
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, std::auto_ptr<ConfigRom>( configRom ) );
1079 #endif
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, std::auto_ptr<ConfigRom>( configRom ) );
1086 #endif
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, std::auto_ptr<ConfigRom>( configRom ) );
1093 #endif
1095 return NULL;
1098 FFADODevice*
1099 DeviceManager::getDriverForDevice( ConfigRom *configRom,
1100 int id )
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;
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;
1117 debugOutput( DEBUG_LEVEL_VERBOSE, " device not supported...\n" );
1118 return NULL;
1121 FFADODevice*
1122 DeviceManager::getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) )
1124 #ifdef ENABLE_BOUNCE
1125 if ( Bounce::SlaveDevice::probe( getConfiguration(), *configRom, false ) ) {
1126 return Bounce::SlaveDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1128 #endif
1129 return NULL;
1132 bool
1133 DeviceManager::isValidNode(int node)
1135 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1136 it != m_avDevices.end();
1137 ++it )
1139 FFADODevice* avDevice = *it;
1141 if (avDevice->getConfigRom().getNodeId() == node) {
1142 return true;
1145 return false;
1149 DeviceManager::getNbDevices()
1151 return m_avDevices.size();
1155 DeviceManager::getDeviceNodeId( int deviceNr )
1157 if ( ! ( deviceNr < getNbDevices() ) ) {
1158 debugError( "Device number out of range (%d)\n", deviceNr );
1159 return -1;
1162 FFADODevice* avDevice = m_avDevices.at( deviceNr );
1164 if ( !avDevice ) {
1165 debugError( "Could not get device at position (%d)\n", deviceNr );
1168 return avDevice->getConfigRom().getNodeId();
1171 FFADODevice*
1172 DeviceManager::getAvDevice( int nodeId )
1174 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1175 it != m_avDevices.end();
1176 ++it )
1178 FFADODevice* avDevice = *it;
1179 if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
1180 return avDevice;
1184 return 0;
1187 FFADODevice*
1188 DeviceManager::getAvDeviceByIndex( int idx )
1190 return m_avDevices.at(idx);
1193 unsigned int
1194 DeviceManager::getAvDeviceCount( )
1196 return m_avDevices.size();
1200 * Return the streamprocessor that is to be used as
1201 * the sync source.
1203 * Algorithm still to be determined
1205 * @return StreamProcessor that is sync source
1207 Streaming::StreamProcessor *
1208 DeviceManager::getSyncSource() {
1209 FFADODevice* device = getAvDeviceByIndex(0);
1211 bool slaveMode=false;
1212 if(!getOption("slaveMode", slaveMode)) {
1213 debugOutput(DEBUG_LEVEL_NORMAL,
1214 "Could not retrieve slaveMode parameter, defauling to false\n");
1216 return device->getStreamProcessorByIndex(0);
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);
1227 bool
1228 DeviceManager::deinitialize()
1230 return true;
1233 void
1234 DeviceManager::setVerboseLevel(int l)
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 )
1245 (*it)->setVerboseLevel(l);
1247 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
1248 it != m_1394Services.end();
1249 ++it )
1251 (*it)->setVerboseLevel(l);
1253 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
1256 void
1257 DeviceManager::showDeviceInfo() {
1258 debugOutput(DEBUG_LEVEL_NORMAL, "===== Device Manager =====\n");
1259 Control::Element::show();
1261 int i=0;
1262 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
1263 it != m_1394Services.end();
1264 ++it )
1266 debugOutput(DEBUG_LEVEL_NORMAL, "--- IEEE1394 Service %2d ---\n", i++);
1267 (*it)->show();
1270 i=0;
1271 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1272 it != m_avDevices.end();
1273 ++it )
1275 FFADODevice* avDevice = *it;
1276 debugOutput(DEBUG_LEVEL_NORMAL, "--- Device %2d ---\n", i++);
1277 avDevice->showDevice();
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 )
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());
1292 void
1293 DeviceManager::showStreamingInfo() {
1294 m_processorManager->dumpInfo();