root/trunk/libffado/src/dice/dice_avdevice.cpp

Revision 1766, 72.7 kB (checked in by arnonym, 13 years ago)

Start some cleanup in the dice-code.

No need for the EAP to be defined inside Dice::Device.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "config.h"
25
26 #include "dice/dice_avdevice.h"
27 #include "dice/dice_defines.h"
28
29 #include "libieee1394/configrom.h"
30 #include "libieee1394/ieee1394service.h"
31
32 #include "debugmodule/debugmodule.h"
33
34 #include "libutil/ByteSwap.h"
35 #include <libraw1394/csr.h>
36
37 #include <stdint.h>
38 #include <iostream>
39 #include <sstream>
40
41 #include <string>
42 #include <cstring>
43 #include <assert.h>
44
45 #include "libutil/Configuration.h"
46 #include "devicemanager.h"
47
48 #include "focusrite/saffire_pro40.h"
49 #include "focusrite/saffire_pro24.h"
50
51 using namespace std;
52
53 namespace Dice {
54
55 Device::Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
56     : FFADODevice( d, configRom )
57     , m_eap( NULL )
58     , m_global_reg_offset (0xFFFFFFFFLU)
59     , m_global_reg_size (0xFFFFFFFFLU)
60     , m_tx_reg_offset (0xFFFFFFFFLU)
61     , m_tx_reg_size (0xFFFFFFFFLU)
62     , m_rx_reg_offset (0xFFFFFFFFLU)
63     , m_rx_reg_size (0xFFFFFFFFLU)
64     , m_unused1_reg_offset (0xFFFFFFFFLU)
65     , m_unused1_reg_size (0xFFFFFFFFLU)
66     , m_unused2_reg_offset (0xFFFFFFFFLU)
67     , m_unused2_reg_size (0xFFFFFFFFLU)
68     , m_nb_tx (0xFFFFFFFFLU)
69     , m_tx_size (0xFFFFFFFFLU)
70     , m_nb_rx (0xFFFFFFFFLU)
71     , m_rx_size (0xFFFFFFFFLU)
72     , m_notifier (NULL)
73 {
74     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Dice::Device (NodeID %d)\n",
75                  getConfigRom().getNodeId() );
76     addOption(Util::OptionContainer::Option("snoopMode", false));
77 }
78
79 Device::~Device()
80 {
81     for ( StreamProcessorVectorIterator it = m_receiveProcessors.begin();
82           it != m_receiveProcessors.end();
83           ++it )
84     {
85         delete *it;
86     }
87     for ( StreamProcessorVectorIterator it = m_transmitProcessors.begin();
88           it != m_transmitProcessors.end();
89           ++it )
90     {
91         delete *it;
92     }
93
94     if (m_notifier) {
95         unlock();
96     }
97
98     if(m_eap) {
99         delete m_eap;
100     }
101
102 }
103
104 bool
105 Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic )
106 {
107     if (generic) {
108         return false;
109     } else {
110         // check if device is in supported devices list
111         unsigned int vendorId = configRom.getNodeVendorId();
112         unsigned int modelId = configRom.getModelId();
113
114         Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
115         return c.isValid(vme) && vme.driver == Util::Configuration::eD_DICE;
116     }
117 }
118
119 FFADODevice *
120 Device::createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
121 {
122     unsigned int vendorId = configRom->getNodeVendorId();
123     unsigned int modelId = configRom->getModelId();
124
125     switch (vendorId) {
126         case FW_VENDORID_FOCUSRITE:
127             switch(modelId) {
128                 case 0x00000005:
129                     return new Focusrite::SaffirePro40(d, configRom);
130                 case 0x00000007:
131                     return new Focusrite::SaffirePro24(d, configRom);
132                 default: // return a plain Dice device
133                     return new Device(d, configRom);
134            }
135         default:
136             return new Device(d, configRom);
137     }
138     return NULL;
139 }
140
141 bool
142 Device::discover()
143 {
144     unsigned int vendorId = getConfigRom().getNodeVendorId();
145     unsigned int modelId = getConfigRom().getModelId();
146
147     Util::Configuration &c = getDeviceManager().getConfiguration();
148     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
149
150     if (c.isValid(vme) && vme.driver == Util::Configuration::eD_DICE) {
151         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
152                      vme.vendor_name.c_str(),
153                      vme.model_name.c_str());
154     } else {
155         debugWarning("Using generic DICE support for unsupported device '%s %s'\n",
156                      getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
157     }
158
159     if ( !initIoFunctions() ) {
160         debugError("Could not initialize I/O functions\n");
161         return false;
162     }
163
164     bool supports_eap = EAP::supportsEAP(*this);
165     if (supports_eap) { // FIXME: move to buildMixer() ??
166         m_eap = createEAP();
167         if(m_eap == NULL) {
168             debugError("Failed to allocate EAP.\n");
169             return false;
170         }
171         if(!m_eap->init()) {
172             debugError("Could not init EAP\n");
173             delete m_eap;
174             m_eap = NULL;
175             return false;
176         }
177         // register the EAP controls to the control structure
178         if(!addElement(m_eap)) {
179             debugError("Failed to add the EAP controls to the control tree\n");
180             return false;
181         }
182     }
183     return true;
184 }
185
186 EAP*
187 Device::createEAP() {
188     return new EAP(*this);
189 }
190
191 enum Device::eDiceConfig
192 Device::getCurrentConfig()
193 {
194     int samplerate = getSamplingFrequency();
195     if(samplerate > 31999 && samplerate <= 48000) {
196         return eDC_Low;
197     }
198     if(samplerate > 48000 && samplerate <= 96000) {
199         return eDC_Mid;
200     }
201     if(samplerate > 96000 && samplerate <= 192000) {
202         return eDC_High;
203     }
204     return eDC_Unknown;
205 }
206
207 int
208 Device::getSamplingFrequency() {
209     int samplingFrequency;
210
211     fb_quadlet_t clockreg;
212     if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg)) {
213         debugError("Could not read CLOCK_SELECT register\n");
214         return false;
215     }
216
217     clockreg = DICE_GET_RATE(clockreg);
218
219     switch (clockreg) {
220         case DICE_RATE_32K:      samplingFrequency = 32000;  break;
221         case DICE_RATE_44K1:     samplingFrequency = 44100;  break;
222         case DICE_RATE_48K:      samplingFrequency = 48000;  break;
223         case DICE_RATE_88K2:     samplingFrequency = 88200;  break;
224         case DICE_RATE_96K:      samplingFrequency = 96000;  break;
225         case DICE_RATE_176K4:    samplingFrequency = 176400; break;
226         case DICE_RATE_192K:     samplingFrequency = 192000; break;
227         case DICE_RATE_ANY_LOW:  samplingFrequency = 0;   break;
228         case DICE_RATE_ANY_MID:  samplingFrequency = 0;   break;
229         case DICE_RATE_ANY_HIGH: samplingFrequency = 0;  break;
230         case DICE_RATE_NONE:     samplingFrequency = 0;     break;
231         default:                 samplingFrequency = 0; break;
232     }
233
234     return samplingFrequency;
235 }
236
237 #define DICE_CHECK_AND_ADD_SR(v, x, reg) \
238     { if(maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, reg)) \
239        v.push_back(x); }
240 std::vector<int>
241 Device::getSupportedSamplingFrequencies()
242 {
243     std::vector<int> frequencies;
244     DICE_CHECK_AND_ADD_SR(frequencies, 32000, DICE_CLOCKCAP_RATE_32K);
245     DICE_CHECK_AND_ADD_SR(frequencies, 44100, DICE_CLOCKCAP_RATE_44K1);
246     DICE_CHECK_AND_ADD_SR(frequencies, 48000, DICE_CLOCKCAP_RATE_48K);
247     DICE_CHECK_AND_ADD_SR(frequencies, 88200, DICE_CLOCKCAP_RATE_88K2);
248     DICE_CHECK_AND_ADD_SR(frequencies, 96000, DICE_CLOCKCAP_RATE_96K);
249     DICE_CHECK_AND_ADD_SR(frequencies, 176400, DICE_CLOCKCAP_RATE_176K4);
250     DICE_CHECK_AND_ADD_SR(frequencies, 192000, DICE_CLOCKCAP_RATE_192K);
251     return frequencies;
252 }
253
254 int
255 Device::getConfigurationId()
256 {
257     return 0;
258 }
259
260 bool
261 Device::setSamplingFrequency( int samplingFrequency )
262 {
263     debugOutput(DEBUG_LEVEL_VERBOSE, "Setting sample rate: %d\n",
264         (samplingFrequency));
265
266     bool supported=false;
267     fb_quadlet_t select=0x0;
268
269     bool snoopMode = false;
270     if(!getOption("snoopMode", snoopMode)) {
271         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
272     }
273
274     if(snoopMode) {
275         int current_sr = getSamplingFrequency();
276         if (current_sr != samplingFrequency ) {
277             debugError("In snoop mode it is impossible to set the sample rate.\n");
278             debugError("Please start the client with the correct setting.\n");
279             return false;
280         }
281         return true;
282     } else {
283         switch ( samplingFrequency ) {
284         default:
285         case 22050:
286         case 24000:
287             supported=false;
288             break;
289         case 32000:
290             supported=maskedCheckNotZeroGlobalReg(
291                         DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES,
292                         DICE_CLOCKCAP_RATE_32K);
293             select=DICE_RATE_32K;
294             break;
295         case 44100:
296             supported=maskedCheckNotZeroGlobalReg(
297                         DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES,
298                         DICE_CLOCKCAP_RATE_44K1);
299             select=DICE_RATE_44K1;
300             break;
301         case 48000:
302             supported=maskedCheckNotZeroGlobalReg(
303                         DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES,
304                         DICE_CLOCKCAP_RATE_48K);
305             select=DICE_RATE_48K;
306             break;
307         case 88200:
308             supported=maskedCheckNotZeroGlobalReg(
309                         DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES,
310                         DICE_CLOCKCAP_RATE_88K2);
311             select=DICE_RATE_88K2;
312             break;
313         case 96000:
314             supported=maskedCheckNotZeroGlobalReg(
315                         DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES,
316                         DICE_CLOCKCAP_RATE_96K);
317             select=DICE_RATE_96K;
318             break;
319         case 176400:
320             supported=maskedCheckNotZeroGlobalReg(
321                         DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES,
322                         DICE_CLOCKCAP_RATE_176K4);
323             select=DICE_RATE_176K4;
324             break;
325         case 192000:
326             supported=maskedCheckNotZeroGlobalReg(
327                         DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES,
328                         DICE_CLOCKCAP_RATE_192K);
329             select=DICE_RATE_192K;
330             break;
331         }
332    
333         if (!supported) {
334             debugWarning("Unsupported sample rate: %d\n", (samplingFrequency));
335             return false;
336         }
337    
338         if (isIsoStreamingEnabled()) {
339             debugError("Cannot change samplerate while streaming is enabled\n");
340             return false;
341         }
342    
343         fb_quadlet_t clockreg;
344         if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg)) {
345             debugError("Could not read CLOCK_SELECT register\n");
346             return false;
347         }
348    
349         clockreg = DICE_SET_RATE(clockreg, select);
350    
351         if (!writeGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, clockreg)) {
352             debugError("Could not write CLOCK_SELECT register\n");
353             return false;
354         }
355    
356         // check if the write succeeded
357         fb_quadlet_t clockreg_verify;
358         if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg_verify)) {
359             debugError("Could not read CLOCK_SELECT register\n");
360             return false;
361         }
362    
363         if(clockreg != clockreg_verify) {
364             debugError("Samplerate register write failed\n");
365             return false;
366         }
367     }
368     return true;
369 }
370
371 FFADODevice::ClockSourceVector
372 Device::getSupportedClockSources() {
373     FFADODevice::ClockSourceVector r;
374
375     quadlet_t clock_caps;
376     readGlobalReg(DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, &clock_caps);
377     uint16_t clocks_supported = (clock_caps >> 16) & 0xFFFF;
378     debugOutput(DEBUG_LEVEL_VERBOSE," Clock caps: 0x%08"PRIX32", supported=0x%04X\n",
379                                     clock_caps, clocks_supported);
380
381     quadlet_t clock_select;
382     readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clock_select);
383     byte_t clock_selected = (clock_select) & 0xFF;
384     debugOutput(DEBUG_LEVEL_VERBOSE," Clock select: 0x%08"PRIX32", selected=0x%04X\n",
385                                     clock_select, clock_selected);
386     quadlet_t extended_status;
387     readGlobalReg(DICE_REGISTER_GLOBAL_EXTENDED_STATUS, &extended_status);
388     #ifdef DEBUG
389     uint16_t clock_status = (extended_status) & 0xFFFF;
390     uint16_t clock_slipping = (extended_status >> 16) & 0xFFFF;
391     debugOutput(DEBUG_LEVEL_VERBOSE," Clock status: 0x%08"PRIX32", status=0x%04X, slip=0x%04X\n",
392                                     extended_status, clock_status, clock_slipping);
393     #endif
394
395     diceNameVector names = getClockSourceNameString();
396     if( names.size() < DICE_CLOCKSOURCE_COUNT) {
397         debugError("Not enough clock source names on device\n");
398         return r;
399     }
400     for (unsigned int i=0; i < DICE_CLOCKSOURCE_COUNT; i++) {
401         bool supported = (((clocks_supported >> i) & 0x01) == 1);
402         if (supported) {
403             ClockSource s;
404             s.type = clockIdToType(i);
405             s.id = i;
406             s.valid = true;
407             s.locked = isClockSourceIdLocked(i, extended_status);
408             s.slipping = isClockSourceIdSlipping(i, extended_status);
409             s.active = (clock_selected == i);
410             s.description = names.at(i);
411             r.push_back(s);
412         } else {
413             debugOutput(DEBUG_LEVEL_VERBOSE, "Clock source id %d not supported by device\n", i);
414         }
415     }
416     return r;
417 }
418
419 bool
420 Device::isClockSourceIdLocked(unsigned int id, quadlet_t ext_status_reg) {
421     switch (id) {
422         default: return true;
423         case  DICE_CLOCKSOURCE_AES1:
424                 return ext_status_reg & DICE_EXT_STATUS_AES0_LOCKED;
425         case  DICE_CLOCKSOURCE_AES2:
426                 return ext_status_reg & DICE_EXT_STATUS_AES1_LOCKED;
427         case  DICE_CLOCKSOURCE_AES3:
428                 return ext_status_reg & DICE_EXT_STATUS_AES2_LOCKED;
429         case  DICE_CLOCKSOURCE_AES4:
430                 return ext_status_reg & DICE_EXT_STATUS_AES3_LOCKED;
431         case  DICE_CLOCKSOURCE_AES_ANY:
432                 return ext_status_reg & DICE_EXT_STATUS_AES_ANY_LOCKED;
433         case  DICE_CLOCKSOURCE_ADAT:
434                 return ext_status_reg & DICE_EXT_STATUS_ADAT_LOCKED;
435         case  DICE_CLOCKSOURCE_TDIF:
436                 return ext_status_reg & DICE_EXT_STATUS_TDIF_LOCKED;
437         case  DICE_CLOCKSOURCE_ARX1:
438                 return ext_status_reg & DICE_EXT_STATUS_ARX1_LOCKED;
439         case  DICE_CLOCKSOURCE_ARX2:
440                 return ext_status_reg & DICE_EXT_STATUS_ARX2_LOCKED;
441         case  DICE_CLOCKSOURCE_ARX3:
442                 return ext_status_reg & DICE_EXT_STATUS_ARX3_LOCKED;
443         case  DICE_CLOCKSOURCE_ARX4:
444                 return ext_status_reg & DICE_EXT_STATUS_ARX4_LOCKED;
445         case  DICE_CLOCKSOURCE_WC:
446                 return ext_status_reg & DICE_EXT_STATUS_WC_LOCKED;
447     }
448 }
449 bool
450 Device::isClockSourceIdSlipping(unsigned int id, quadlet_t ext_status_reg) {
451     switch (id) {
452         default: return false;
453         case  DICE_CLOCKSOURCE_AES1:
454                 return ext_status_reg & DICE_EXT_STATUS_AES0_SLIP;
455         case  DICE_CLOCKSOURCE_AES2:
456                 return ext_status_reg & DICE_EXT_STATUS_AES1_SLIP;
457         case  DICE_CLOCKSOURCE_AES3:
458                 return ext_status_reg & DICE_EXT_STATUS_AES2_SLIP;
459         case  DICE_CLOCKSOURCE_AES4:
460                 return ext_status_reg & DICE_EXT_STATUS_AES3_SLIP;
461         case  DICE_CLOCKSOURCE_AES_ANY:
462                 return false;
463         case  DICE_CLOCKSOURCE_ADAT:
464                 return ext_status_reg & DICE_EXT_STATUS_ADAT_SLIP;
465         case  DICE_CLOCKSOURCE_TDIF:
466                 return ext_status_reg & DICE_EXT_STATUS_TDIF_SLIP;
467         case  DICE_CLOCKSOURCE_ARX1:
468                 return ext_status_reg & DICE_EXT_STATUS_ARX1_SLIP;
469         case  DICE_CLOCKSOURCE_ARX2:
470                 return ext_status_reg & DICE_EXT_STATUS_ARX2_SLIP;
471         case  DICE_CLOCKSOURCE_ARX3:
472                 return ext_status_reg & DICE_EXT_STATUS_ARX3_SLIP;
473         case  DICE_CLOCKSOURCE_ARX4:
474                 return ext_status_reg & DICE_EXT_STATUS_ARX4_SLIP;
475         case  DICE_CLOCKSOURCE_WC: // FIXME: not in driver spec, so non-existant
476                 return ext_status_reg & DICE_EXT_STATUS_WC_SLIP;
477     }
478 }
479
480 enum FFADODevice::eClockSourceType
481 Device::clockIdToType(unsigned int id) {
482     switch (id) {
483         default: return eCT_Invalid;
484         case  DICE_CLOCKSOURCE_AES1:
485         case  DICE_CLOCKSOURCE_AES2:
486         case  DICE_CLOCKSOURCE_AES3:
487         case  DICE_CLOCKSOURCE_AES4:
488         case  DICE_CLOCKSOURCE_AES_ANY:
489                 return eCT_AES;
490         case  DICE_CLOCKSOURCE_ADAT:
491                 return eCT_ADAT;
492         case  DICE_CLOCKSOURCE_TDIF:
493                 return eCT_TDIF;
494         case  DICE_CLOCKSOURCE_ARX1:
495         case  DICE_CLOCKSOURCE_ARX2:
496         case  DICE_CLOCKSOURCE_ARX3:
497         case  DICE_CLOCKSOURCE_ARX4:
498                 return eCT_SytMatch;
499         case  DICE_CLOCKSOURCE_WC:
500                 return eCT_WordClock;
501         case DICE_CLOCKSOURCE_INTERNAL:
502                 return eCT_Internal;
503     }
504 }
505
506 bool
507 Device::setActiveClockSource(ClockSource s) {
508     fb_quadlet_t clockreg;
509     if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg)) {
510         debugError("Could not read CLOCK_SELECT register\n");
511         return false;
512     }
513
514     clockreg = DICE_SET_CLOCKSOURCE(clockreg, s.id);
515
516     if (!writeGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, clockreg)) {
517         debugError("Could not write CLOCK_SELECT register\n");
518         return false;
519     }
520
521     // check if the write succeeded
522     fb_quadlet_t clockreg_verify;
523     if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg_verify)) {
524         debugError("Could not read CLOCK_SELECT register\n");
525         return false;
526     }
527
528     if(clockreg != clockreg_verify) {
529         debugError("CLOCK_SELECT register write failed\n");
530         return false;
531     }
532
533     return DICE_GET_CLOCKSOURCE(clockreg_verify) == s.id;
534 }
535
536 FFADODevice::ClockSource
537 Device::getActiveClockSource() {
538     ClockSource s;
539     quadlet_t clock_caps;
540     readGlobalReg(DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, &clock_caps);
541     uint16_t clocks_supported = (clock_caps >> 16) & 0xFFFF;
542     debugOutput(DEBUG_LEVEL_VERBOSE," Clock caps: 0x%08"PRIX32", supported=0x%04X\n",
543                                     clock_caps, clocks_supported);
544
545     quadlet_t clock_select;
546     readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clock_select);
547     byte_t id = (clock_select) & 0xFF;
548     debugOutput(DEBUG_LEVEL_VERBOSE," Clock select: 0x%08"PRIX32", selected=0x%04X\n",
549                                     clock_select, id);
550     quadlet_t extended_status;
551     readGlobalReg(DICE_REGISTER_GLOBAL_EXTENDED_STATUS, &extended_status);
552     #ifdef DEBUG
553     uint16_t clock_status = (extended_status) & 0xFFFF;
554     uint16_t clock_slipping = (extended_status >> 16) & 0xFFFF;
555     debugOutput(DEBUG_LEVEL_VERBOSE," Clock status: 0x%08"PRIX32", status=0x%04X, slip=0x%04X\n",
556                                     extended_status, clock_status, clock_slipping);
557     #endif
558
559     diceNameVector names = getClockSourceNameString();
560     if( names.size() < DICE_CLOCKSOURCE_COUNT) {
561         debugError("Not enough clock source names on device\n");
562         return s;
563     }
564     bool supported = (((clocks_supported >> id) & 0x01) == 1);
565     if (supported) {
566         s.type = clockIdToType(id);
567         s.id = id;
568         s.valid = true;
569         s.locked = isClockSourceIdLocked(id, extended_status);
570         s.slipping = isClockSourceIdSlipping(id, extended_status);
571         s.active = true;
572         s.description = names.at(id);
573     } else {
574         debugOutput(DEBUG_LEVEL_VERBOSE, "Clock source id %2d not supported by device\n", id);
575     }
576     return s;
577 }
578
579 bool
580 Device::setNickname( std::string name)
581 {
582     return setDeviceNickName(name);
583 }
584
585 std::string
586 Device::getNickname()
587 {
588     return getDeviceNickName();
589 }
590
591 void
592 Device::showDevice()
593 {
594     fb_quadlet_t tmp_quadlet;
595     fb_octlet_t tmp_octlet;
596
597     debugOutput(DEBUG_LEVEL_NORMAL, "Device is a DICE device\n");
598     FFADODevice::showDevice();
599
600     debugOutput(DEBUG_LEVEL_VERBOSE," DICE Parameter Space info:\n");
601     debugOutput(DEBUG_LEVEL_VERBOSE,"  Global  : offset=0x%04X size=%04d\n", m_global_reg_offset, m_global_reg_size);
602     debugOutput(DEBUG_LEVEL_VERBOSE,"  TX      : offset=0x%04X size=%04d\n", m_tx_reg_offset, m_tx_reg_size);
603     debugOutput(DEBUG_LEVEL_VERBOSE,"                nb=%4d size=%04d\n", m_nb_tx, m_tx_size);
604     debugOutput(DEBUG_LEVEL_VERBOSE,"  RX      : offset=0x%04X size=%04d\n", m_rx_reg_offset, m_rx_reg_size);
605     debugOutput(DEBUG_LEVEL_VERBOSE,"                nb=%4d size=%04d\n", m_nb_rx, m_rx_size);
606     debugOutput(DEBUG_LEVEL_VERBOSE,"  UNUSED1 : offset=0x%04X size=%04d\n", m_unused1_reg_offset, m_unused1_reg_size);
607     debugOutput(DEBUG_LEVEL_VERBOSE,"  UNUSED2 : offset=0x%04X size=%04d\n", m_unused2_reg_offset, m_unused2_reg_size);
608
609     debugOutput(DEBUG_LEVEL_VERBOSE," Global param space:\n");
610
611     readGlobalRegBlock(DICE_REGISTER_GLOBAL_OWNER, reinterpret_cast<fb_quadlet_t *>(&tmp_octlet), sizeof(fb_octlet_t));
612     debugOutput(DEBUG_LEVEL_VERBOSE,"  Owner            : 0x%016"PRIX64"\n",tmp_octlet);
613
614     readGlobalReg(DICE_REGISTER_GLOBAL_NOTIFICATION, &tmp_quadlet);
615     debugOutput(DEBUG_LEVEL_VERBOSE,"  Notification     : 0x%08"PRIX32"\n",tmp_quadlet);
616
617     readGlobalReg(DICE_REGISTER_GLOBAL_NOTIFICATION, &tmp_quadlet);
618     debugOutput(DEBUG_LEVEL_NORMAL,"  Nick name        : %s\n",getDeviceNickName().c_str());
619
620     readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &tmp_quadlet);
621     debugOutput(DEBUG_LEVEL_NORMAL,"  Clock Select     : 0x%02X 0x%02X\n",
622         (tmp_quadlet>>8) & 0xFF, tmp_quadlet & 0xFF);
623
624     readGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, &tmp_quadlet);
625     debugOutput(DEBUG_LEVEL_NORMAL,"  Enable           : %s\n",
626         (tmp_quadlet&0x1?"true":"false"));
627
628     readGlobalReg(DICE_REGISTER_GLOBAL_STATUS, &tmp_quadlet);
629     debugOutput(DEBUG_LEVEL_NORMAL,"  Clock Status     : %s 0x%02X\n",
630         (tmp_quadlet&0x1?"locked":"not locked"), (tmp_quadlet>>8) & 0xFF);
631
632     readGlobalReg(DICE_REGISTER_GLOBAL_EXTENDED_STATUS, &tmp_quadlet);
633     debugOutput(DEBUG_LEVEL_VERBOSE, "  Extended Status  : 0x%08"PRIX32"\n", tmp_quadlet);
634
635     readGlobalReg(DICE_REGISTER_GLOBAL_SAMPLE_RATE, &tmp_quadlet);
636     debugOutput(DEBUG_LEVEL_NORMAL, "  Samplerate       : 0x%08"PRIX32" (%"PRIu32")\n", tmp_quadlet, tmp_quadlet);
637
638     readGlobalRegBlock(DICE_REGISTER_GLOBAL_VERSION, reinterpret_cast<fb_quadlet_t *>(&tmp_quadlet), sizeof(fb_quadlet_t));
639     debugOutput(DEBUG_LEVEL_NORMAL,"  Version          : 0x%08"PRIX32"\n", tmp_quadlet);
640    
641     readGlobalReg(DICE_REGISTER_GLOBAL_VERSION, &tmp_quadlet);
642     debugOutput(DEBUG_LEVEL_NORMAL,"  Version          : 0x%08"PRIX32" (%u.%u.%u.%u)\n",
643         tmp_quadlet,
644         DICE_DRIVER_SPEC_VERSION_NUMBER_GET_A(tmp_quadlet),
645         DICE_DRIVER_SPEC_VERSION_NUMBER_GET_B(tmp_quadlet),
646         DICE_DRIVER_SPEC_VERSION_NUMBER_GET_C(tmp_quadlet),
647         DICE_DRIVER_SPEC_VERSION_NUMBER_GET_D(tmp_quadlet)
648         );
649
650     readGlobalReg(DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, &tmp_quadlet);
651     debugOutput(DEBUG_LEVEL_VERBOSE,"  Clock caps       : 0x%08"PRIX32"\n", tmp_quadlet);
652
653     diceNameVector names=getClockSourceNameString();
654     debugOutput(DEBUG_LEVEL_VERBOSE,"  Clock sources    :\n");
655
656     for ( diceNameVectorIterator it = names.begin();
657           it != names.end();
658           ++it )
659     {
660         debugOutput(DEBUG_LEVEL_VERBOSE,"    %s\n", (*it).c_str());
661     }
662
663     debugOutput(DEBUG_LEVEL_VERBOSE," TX param space:\n");
664     debugOutput(DEBUG_LEVEL_VERBOSE,"  Nb of xmit        : %1d\n", m_nb_tx);
665     for (unsigned int i=0;i<m_nb_tx;i++) {
666         debugOutput(DEBUG_LEVEL_VERBOSE,"  Transmitter %d:\n",i);
667
668         readTxReg(i, DICE_REGISTER_TX_ISOC_BASE, &tmp_quadlet);
669         debugOutput(DEBUG_LEVEL_VERBOSE,"   ISO channel       : %3d\n", tmp_quadlet);
670         readTxReg(i, DICE_REGISTER_TX_SPEED_BASE, &tmp_quadlet);
671         debugOutput(DEBUG_LEVEL_VERBOSE,"   ISO speed         : %3d\n", tmp_quadlet);
672
673         readTxReg(i, DICE_REGISTER_TX_NB_AUDIO_BASE, &tmp_quadlet);
674         debugOutput(DEBUG_LEVEL_VERBOSE,"   Nb audio channels : %3d\n", tmp_quadlet);
675         readTxReg(i, DICE_REGISTER_TX_MIDI_BASE, &tmp_quadlet);
676         debugOutput(DEBUG_LEVEL_VERBOSE,"   Nb midi channels  : %3d\n", tmp_quadlet);
677
678         readTxReg(i, DICE_REGISTER_TX_AC3_CAPABILITIES_BASE, &tmp_quadlet);
679         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 caps          : 0x%08"PRIX32"\n", tmp_quadlet);
680         readTxReg(i, DICE_REGISTER_TX_AC3_ENABLE_BASE, &tmp_quadlet);
681         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 enable        : 0x%08"PRIX32"\n", tmp_quadlet);
682
683         diceNameVector channel_names=getTxNameString(i);
684         debugOutput(DEBUG_LEVEL_VERBOSE,"   Channel names     :\n");
685         for ( diceNameVectorIterator it = channel_names.begin();
686             it != channel_names.end();
687             ++it )
688         {
689             debugOutput(DEBUG_LEVEL_VERBOSE,"     %s\n", (*it).c_str());
690         }
691     }
692
693     debugOutput(DEBUG_LEVEL_VERBOSE," RX param space:\n");
694     debugOutput(DEBUG_LEVEL_VERBOSE,"  Nb of recv        : %1d\n", m_nb_tx);
695     for (unsigned int i=0;i<m_nb_rx;i++) {
696         debugOutput(DEBUG_LEVEL_VERBOSE,"  Receiver %d:\n",i);
697
698         readTxReg(i, DICE_REGISTER_RX_ISOC_BASE, &tmp_quadlet);
699         debugOutput(DEBUG_LEVEL_VERBOSE,"   ISO channel       : %3d\n", tmp_quadlet);
700         readTxReg(i, DICE_REGISTER_RX_SEQ_START_BASE, &tmp_quadlet);
701         debugOutput(DEBUG_LEVEL_VERBOSE,"   Sequence start    : %3d\n", tmp_quadlet);
702
703         readTxReg(i, DICE_REGISTER_RX_NB_AUDIO_BASE, &tmp_quadlet);
704         debugOutput(DEBUG_LEVEL_VERBOSE,"   Nb audio channels : %3d\n", tmp_quadlet);
705         readTxReg(i, DICE_REGISTER_RX_MIDI_BASE, &tmp_quadlet);
706         debugOutput(DEBUG_LEVEL_VERBOSE,"   Nb midi channels  : %3d\n", tmp_quadlet);
707
708         readTxReg(i, DICE_REGISTER_RX_AC3_CAPABILITIES_BASE, &tmp_quadlet);
709         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 caps          : 0x%08"PRIX32"\n", tmp_quadlet);
710         readTxReg(i, DICE_REGISTER_RX_AC3_ENABLE_BASE, &tmp_quadlet);
711         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 enable        : 0x%08"PRIX32"\n", tmp_quadlet);
712
713         diceNameVector channel_names=getRxNameString(i);
714         debugOutput(DEBUG_LEVEL_VERBOSE,"   Channel names     :\n");
715         for ( diceNameVectorIterator it = channel_names.begin();
716             it != channel_names.end();
717             ++it )
718         {
719             debugOutput(DEBUG_LEVEL_VERBOSE,"     %s\n", (*it).c_str());
720         }
721     }
722     flushDebugOutput();
723 }
724
725 // NOTE on bandwidth calculation
726 // FIXME: The bandwidth allocation calculation can probably be
727 // refined somewhat since this is currently based on a rudimentary
728 // understanding of the iso protocol.
729 // Currently we assume the following.
730 //   * Ack/iso gap = 0.05 us
731 //   * DATA_PREFIX = 0.16 us1
732 //   * DATA_END    = 0.26 us
733 // These numbers are the worst-case figures given in the ieee1394
734 // standard.  This gives approximately 0.5 us of overheads per
735 // packet - around 25 bandwidth allocation units (from the ieee1394
736 // standard 1 bandwidth allocation unit is 125/6144 us).  We further
737 // assume the device is running at S400 (which it should be) so one
738 // allocation unit is equivalent to 1 transmitted byte; thus the
739 // bandwidth allocation required for the packets themselves is just
740 // the size of the packet.
741 bool
742 Device::prepare() {
743     fb_quadlet_t nb_audio;
744     fb_quadlet_t nb_midi;
745     unsigned int nb_channels = 0;
746
747     bool snoopMode = false;
748     if(!getOption("snoopMode", snoopMode)) {
749         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
750     }
751
752     // get the device specific and/or global SP configuration
753     Util::Configuration &config = getDeviceManager().getConfiguration();
754     // base value is the config.h value
755     float recv_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ;
756     float xmit_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ;
757
758     int xmit_max_cycles_early_transmit = AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY;
759     int xmit_transfer_delay = AMDTP_TRANSMIT_TRANSFER_DELAY;
760     int xmit_min_cycles_before_presentation = AMDTP_MIN_CYCLES_BEFORE_PRESENTATION;
761
762     // we can override that globally
763     config.getValueForSetting("streaming.common.recv_sp_dll_bw", recv_sp_dll_bw);
764     config.getValueForSetting("streaming.common.xmit_sp_dll_bw", xmit_sp_dll_bw);
765     config.getValueForSetting("streaming.amdtp.xmit_max_cycles_early_transmit", xmit_max_cycles_early_transmit);
766     config.getValueForSetting("streaming.amdtp.xmit_transfer_delay", xmit_transfer_delay);
767     config.getValueForSetting("streaming.amdtp.xmit_min_cycles_before_presentation", xmit_min_cycles_before_presentation);
768
769     // or override in the device section
770     uint32_t vendorid = getConfigRom().getNodeVendorId();
771     uint32_t modelid = getConfigRom().getModelId();
772     config.getValueForDeviceSetting(vendorid, modelid, "recv_sp_dll_bw", recv_sp_dll_bw);
773     config.getValueForDeviceSetting(vendorid, modelid, "xmit_sp_dll_bw", xmit_sp_dll_bw);
774     config.getValueForDeviceSetting(vendorid, modelid, "xmit_max_cycles_early_transmit", xmit_max_cycles_early_transmit);
775     config.getValueForDeviceSetting(vendorid, modelid, "xmit_transfer_delay", xmit_transfer_delay);
776     config.getValueForDeviceSetting(vendorid, modelid, "xmit_min_cycles_before_presentation", xmit_min_cycles_before_presentation);
777
778     diceNameVector names_audio;
779     diceNameVector names_midi;
780     // prepare receive SP's
781 //     for (unsigned int i=0;i<1;i++) {
782     for (unsigned int i=0; i<m_nb_tx; i++) {
783
784         if(!readTxReg(i, DICE_REGISTER_TX_NB_AUDIO_BASE, &nb_audio)) {
785             debugError("Could not read DICE_REGISTER_TX_NB_AUDIO_BASE register for ATX%u\n",i);
786             continue;
787         }
788         if(!readTxReg(i, DICE_REGISTER_TX_MIDI_BASE, &nb_midi)) {
789             debugError("Could not read DICE_REGISTER_TX_MIDI_BASE register for ATX%u\n",i);
790             continue;
791         }
792
793         // request the channel names
794         names_audio = getTxNameString(i);
795         if (names_audio.size() != nb_audio) {
796             debugWarning("The audio channel name vector is incorrect, using default names\n");
797             names_audio.clear();
798
799             for (unsigned int j=0;j<nb_audio;j++) {
800                 std::ostringstream newname;
801                 newname << "input_" << j;
802                 names_audio.push_back(newname.str());
803             }
804         }
805
806         nb_channels = nb_audio;
807         if(nb_midi) nb_channels += 1; // midi-muxed counts as one
808
809         // construct the MIDI names
810         for (unsigned int j=0;j<nb_midi;j++) {
811             std::ostringstream newname;
812             newname << "midi_in_" << j;
813             names_midi.push_back(newname.str());
814         }
815
816         // construct the streamprocessor
817         Streaming::AmdtpReceiveStreamProcessor *p;
818         p = new Streaming::AmdtpReceiveStreamProcessor(*this,
819                              nb_channels);
820
821         if(!p->init()) {
822             debugFatal("Could not initialize receive processor!\n");
823             delete p;
824             continue;
825         }
826
827         // add audio ports to the processor
828         for (unsigned int j=0;j<nb_audio;j++) {
829             diceChannelInfo channelInfo;
830             channelInfo.name=names_audio.at(j);
831             channelInfo.portType=ePT_Analog;
832             channelInfo.streamPosition=j;
833             channelInfo.streamLocation=0;
834
835             if (!addChannelToProcessor(&channelInfo, p, Streaming::Port::E_Capture)) {
836                 debugError("Could not add channel %s to StreamProcessor\n",
837                     channelInfo.name.c_str());
838                 continue;
839             }
840         }
841
842         // add midi ports to the processor
843         for (unsigned int j=0;j<nb_midi;j++) {
844             diceChannelInfo channelInfo;
845             channelInfo.name=names_midi.at(j);
846             channelInfo.portType=ePT_MIDI;
847             channelInfo.streamPosition=nb_audio;
848             channelInfo.streamLocation=j;
849
850             if (!addChannelToProcessor(&channelInfo, p, Streaming::Port::E_Capture)) {
851                 debugError("Could not add channel %s to StreamProcessor\n",
852                     channelInfo.name.c_str());
853                 continue;
854             }
855         }
856
857         if(!p->setDllBandwidth(recv_sp_dll_bw)) {
858             debugFatal("Could not set DLL bandwidth\n");
859             delete p;
860             return false;
861         }
862
863         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Receive SP on channel [%d audio, %d midi]\n", this, nb_audio, nb_midi);
864         // add the SP to the vector
865         m_receiveProcessors.push_back(p);
866     }
867
868     // prepare transmit SP's
869     names_audio.clear();
870     names_midi.clear();
871 //     for (unsigned int i=0;i<1;i++) {
872     for (unsigned int i=0; i<m_nb_rx; i++) {
873
874         // construct the streamprocessor
875         Streaming::StreamProcessor *p;
876         if(!readRxReg(i, DICE_REGISTER_RX_NB_AUDIO_BASE, &nb_audio)) {
877             debugError("Could not read DICE_REGISTER_RX_NB_AUDIO_BASE register for ARX%u\n", i);
878             continue;
879         }
880         if(!readRxReg(i, DICE_REGISTER_RX_MIDI_BASE, &nb_midi)) {
881             debugError("Could not read DICE_REGISTER_RX_MIDI_BASE register for ARX%u\n", i);
882             continue;
883         }
884
885         // request the channel names
886         names_audio = getRxNameString(i);
887
888         /* Vendor-specific hacks */
889         // PP: I think this was a workaround for a bug that is not required anymore
890         #if 0
891         if (FW_VENDORID_ALESIS == getConfigRom().getNodeVendorId()) {
892             /* Alesis io14 RX0 claims to have six audio channels. Ignore
893             * it, just use 8 for Bus1-L+R .. Bus4-L+R.
894             */
895             if (0x00000001 == getConfigRom().getModelId()) {
896                 nb_audio = 8;
897             }
898
899             /* Alesis Multimix16 RX0 only has two channels, Main-Out L+R */
900             if (0x00000000 == getConfigRom().getModelId()) {
901                 nb_audio = 2;
902             }
903         }
904         #endif
905
906         nb_channels = nb_audio;
907         if(nb_midi) nb_channels += 1; // midi-muxed counts as one
908
909         if (names_audio.size() != nb_audio) {
910             debugWarning("The audio channel name vector is incorrect, using default names\n");
911             names_audio.clear();
912
913             for (unsigned int j=0; j < nb_audio; j++) {
914                 std::ostringstream newname;
915                 newname << "output_" << j;
916                 names_audio.push_back(newname.str());
917             }
918         }
919
920         // construct the MIDI names
921         for (unsigned int j=0; j < nb_midi; j++) {
922             std::ostringstream newname;
923             newname << "midi_out_" << j;
924             names_midi.push_back(newname.str());
925         }
926
927         enum Streaming::Port::E_Direction port_type;
928         float dll_bw;
929         if (snoopMode) {
930             // we are snooping, so this is receive too.
931             p = new Streaming::AmdtpReceiveStreamProcessor(*this, nb_channels);
932             port_type = Streaming::Port::E_Capture;
933             dll_bw = recv_sp_dll_bw;
934         } else {
935             // this is a normal situation
936             Streaming::AmdtpTransmitStreamProcessor *t;
937             t = new Streaming::AmdtpTransmitStreamProcessor(*this, nb_channels);
938             #if AMDTP_ALLOW_PAYLOAD_IN_NODATA_XMIT
939             // the DICE-II cannot handle payload in the NO-DATA packets.
940             // the other DICE chips don't need payload. Therefore
941             // we disable it.
942             t->sendPayloadForNoDataPackets(false);
943             #endif
944    
945             // transmit control parameters
946             t->setMaxCyclesToTransmitEarly(xmit_max_cycles_early_transmit);
947             t->setTransferDelay(xmit_transfer_delay);
948             t->setMinCyclesBeforePresentation(xmit_min_cycles_before_presentation);
949
950             p = t;
951             port_type = Streaming::Port::E_Playback;
952             dll_bw = xmit_sp_dll_bw;
953         }
954
955         if(!p->init()) {
956             debugFatal("Could not initialize transmit processor %s!\n",
957                 (snoopMode?" in snoop mode":""));
958             delete p;
959             continue;
960         }
961
962         // add audio ports to the processor
963         for (unsigned int j=0; j < nb_audio; j++) {
964             diceChannelInfo channelInfo;
965             channelInfo.name = names_audio.at(j);
966             channelInfo.portType = ePT_Analog;
967             channelInfo.streamPosition = j;
968             channelInfo.streamLocation = 0;
969
970             if (!addChannelToProcessor(&channelInfo, p, port_type)) {
971                 debugError("Could not add channel %s to StreamProcessor\n",
972                     channelInfo.name.c_str());
973                 continue;
974             }
975         }
976
977         // add midi ports to the processor
978         for (unsigned int j=0; j < nb_midi; j++) {
979             diceChannelInfo channelInfo;
980             channelInfo.name = names_midi.at(j);
981             channelInfo.portType = ePT_MIDI;
982             channelInfo.streamPosition = nb_audio;
983             channelInfo.streamLocation = j;
984
985             if (!addChannelToProcessor(&channelInfo, p, port_type)) {
986                 debugError("Could not add channel %s to StreamProcessor\n",
987                     channelInfo.name.c_str());
988                 continue;
989             }
990         }
991
992         // set DLL bandwidth
993         if(!p->setDllBandwidth(recv_sp_dll_bw)) {
994             debugFatal("Could not set DLL bandwidth\n");
995             delete p;
996             return false;
997         }
998        
999         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Transmit SP on channel [%d audio, %d midi]%s\n",
1000                                          this, nb_audio, nb_midi, (snoopMode?" snoop mode":""));
1001
1002         // we put this SP into the transmit SP vector,
1003         // no matter if we are in snoop mode or not
1004         // this allows us to find out what direction
1005         // a certain stream should have.
1006         m_transmitProcessors.push_back(p);
1007     }
1008     return true;
1009 }
1010
1011 bool
1012 Device::addChannelToProcessor(
1013     diceChannelInfo *channelInfo,
1014     Streaming::StreamProcessor *processor,
1015     Streaming::Port::E_Direction direction) {
1016
1017     std::string id=std::string("dev?");
1018     if(!getOption("id", id)) {
1019         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
1020     }
1021
1022     std::ostringstream portname;
1023     portname << id;
1024     if(direction == Streaming::Port::E_Playback) {
1025         portname << "p";
1026     } else {
1027         portname << "c";
1028     }
1029
1030     portname << "_" << channelInfo->name;
1031
1032     Streaming::Port *p=NULL;
1033     switch(channelInfo->portType) {
1034     case ePT_Analog:
1035         p=new Streaming::AmdtpAudioPort(
1036                 *processor,
1037                 portname.str(),
1038                 direction,
1039                 channelInfo->streamPosition,
1040                 channelInfo->streamLocation,
1041                 Streaming::AmdtpPortInfo::E_MBLA
1042         );
1043         break;
1044
1045     case ePT_MIDI:
1046         p=new Streaming::AmdtpMidiPort(
1047                 *processor,
1048                 portname.str(),
1049                 direction,
1050                 channelInfo->streamPosition,
1051                 channelInfo->streamLocation,
1052                 Streaming::AmdtpPortInfo::E_Midi
1053         );
1054
1055         break;
1056     default:
1057     // unsupported
1058         break;
1059     }
1060
1061     if (!p) {
1062         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->name.c_str());
1063     }
1064
1065     return true;
1066 }
1067
1068 bool
1069 Device::lock() {
1070     fb_octlet_t result;
1071
1072     debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device at node %d\n", getNodeId());
1073
1074     bool snoopMode = false;
1075     if(!getOption("snoopMode", snoopMode)) {
1076         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1077     }
1078
1079     if (snoopMode) {
1080         debugWarning("Lock not supported in snoop mode\n");
1081         return true; //FIXME: this should be false
1082     } else {
1083
1084     // get a notifier to handle device notifications
1085         nodeaddr_t notify_address;
1086         notify_address = get1394Service().findFreeARMBlock(
1087                             DICE_NOTIFIER_BASE_ADDRESS,
1088                             DICE_NOTIFIER_BLOCK_LENGTH,
1089                             DICE_NOTIFIER_BLOCK_LENGTH);
1090    
1091         if (notify_address == 0xFFFFFFFFFFFFFFFFLLU) {
1092             debugError("Could not find free ARM block for notification\n");
1093             return false;
1094         }
1095    
1096         m_notifier = new Device::Notifier(*this, notify_address);
1097    
1098         if(!m_notifier) {
1099             debugError("Could not allocate notifier\n");
1100             return false;
1101         }
1102    
1103         if (!get1394Service().registerARMHandler(m_notifier)) {
1104             debugError("Could not register notifier\n");
1105             delete m_notifier;
1106             m_notifier=NULL;
1107             return false;
1108         }
1109    
1110         // register this notifier
1111         fb_nodeaddr_t addr = DICE_REGISTER_BASE
1112                         + m_global_reg_offset
1113                         + DICE_REGISTER_GLOBAL_OWNER;
1114    
1115         // registry offsets should always be smaller than 0x7FFFFFFF
1116         // because otherwise base + offset > 64bit
1117         if(m_global_reg_offset & 0x80000000) {
1118             debugError("register offset not initialized yet\n");
1119             return false;
1120         }
1121    
1122         fb_nodeaddr_t swap_value = ((0xFFC0) | get1394Service().getLocalNodeId());
1123         swap_value = swap_value << 48;
1124         swap_value |= m_notifier->getStart();
1125    
1126         if (!get1394Service().lockCompareSwap64(getNodeId() | 0xFFC0,
1127                                                 addr, DICE_OWNER_NO_OWNER,
1128                                                 swap_value, &result )) {
1129             debugWarning("Could not register ourselves as device owner\n");
1130             return false;
1131         }
1132    
1133         if (result != DICE_OWNER_NO_OWNER) {
1134             debugWarning("Could not register ourselves as device owner, unexpected register value: 0x%016"PRIX64"\n", result);
1135             return false;
1136         }
1137    
1138         return true;
1139     }
1140 }
1141
1142
1143 bool
1144 Device::unlock() {
1145     fb_octlet_t result;
1146
1147     bool snoopMode = false;
1148     if(!getOption("snoopMode", snoopMode)) {
1149         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1150     }
1151
1152     if (snoopMode) {
1153         debugWarning("Unlock not supported in snoop mode\n");
1154         return true; //FIXME: this should be false
1155     } else {
1156         if(!m_notifier) {
1157             debugWarning("Request to unlock, but no notifier present!\n");
1158             return false;
1159         }
1160    
1161         fb_nodeaddr_t addr = DICE_REGISTER_BASE
1162                         + m_global_reg_offset
1163                         + DICE_REGISTER_GLOBAL_OWNER;
1164    
1165         // registry offsets should always be smaller than 0x7FFFFFFF
1166         // because otherwise base + offset > 64bit
1167         if(m_global_reg_offset & 0x80000000) {
1168             debugError("register offset not initialized yet\n");
1169             return false;
1170         }
1171    
1172         fb_nodeaddr_t compare_value = ((0xFFC0) | get1394Service().getLocalNodeId());
1173         compare_value <<= 48;
1174         compare_value |= m_notifier->getStart();
1175    
1176         if (!get1394Service().lockCompareSwap64(  getNodeId() | 0xFFC0, addr, compare_value,
1177                                         DICE_OWNER_NO_OWNER, &result )) {
1178             debugWarning("Could not unregister ourselves as device owner\n");
1179             return false;
1180         }
1181    
1182         get1394Service().unregisterARMHandler(m_notifier);
1183         delete m_notifier;
1184         m_notifier=NULL;
1185    
1186         return true;
1187     }
1188 }
1189
1190 bool
1191 Device::enableStreaming() {
1192     bool snoopMode = false;
1193     if(!getOption("snoopMode", snoopMode)) {
1194         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1195     }
1196
1197     if (snoopMode) {
1198         debugWarning("Stream should be already running for snoop mode\n");
1199         return true;
1200     } else {
1201         return enableIsoStreaming();
1202     }
1203 }
1204
1205 bool
1206 Device::disableStreaming() {
1207     bool snoopMode = false;
1208     if(!getOption("snoopMode", snoopMode)) {
1209         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1210     }
1211
1212     if (snoopMode) {
1213         debugWarning("Won't disable stream in snoop mode\n");
1214         return true;
1215     } else {
1216         return disableIsoStreaming();
1217     }
1218 }
1219
1220 int
1221 Device::getStreamCount() {
1222     return m_receiveProcessors.size() + m_transmitProcessors.size();
1223 }
1224
1225 Streaming::StreamProcessor *
1226 Device::getStreamProcessorByIndex(int i) {
1227
1228     if (i<(int)m_receiveProcessors.size()) {
1229         return m_receiveProcessors.at(i);
1230     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1231         return m_transmitProcessors.at(i-m_receiveProcessors.size());
1232     }
1233
1234     return NULL;
1235 }
1236
1237 bool
1238 Device::startStreamByIndex(int i) {
1239     bool snoopMode = false;
1240     if(!getOption("snoopMode", snoopMode)) {
1241         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1242     }
1243
1244     if (!snoopMode && isIsoStreamingEnabled()) {
1245         debugError("Cannot start streams while streaming is enabled\n");
1246         return false;
1247     }
1248
1249     if (i<(int)m_receiveProcessors.size()) {
1250         int n=i;
1251         Streaming::StreamProcessor *p = m_receiveProcessors.at(n);
1252
1253         if(snoopMode) { // a stream from the device to another host
1254             fb_quadlet_t reg_isoch;
1255             // check value of ISO_CHANNEL register
1256             if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) {
1257                 debugError("Could not read ISO_CHANNEL register for ATX %d\n", n);
1258                 p->setChannel(-1);
1259                 return false;
1260             }
1261             int isochannel = reg_isoch;
1262             debugOutput(DEBUG_LEVEL_VERBOSE,
1263                         "(%p) Snooping RX from channel %d\n",
1264                         this, isochannel);
1265             p->setChannel(isochannel);
1266         } else {
1267             // allocate ISO channel
1268             int isochannel = allocateIsoChannel(p->getMaxPacketSize());
1269             if(isochannel<0) {
1270                 debugError("Could not allocate iso channel for SP %d (ATX %d)\n", i, n);
1271                 return false;
1272             }
1273             debugOutput(DEBUG_LEVEL_VERBOSE,
1274                         "(%p) Allocated channel %u for RX\n",
1275                         this, isochannel);
1276             p->setChannel(isochannel);
1277    
1278             fb_quadlet_t reg_isoch;
1279             // check value of ISO_CHANNEL register
1280             if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) {
1281                 debugError("Could not read ISO_CHANNEL register for ATX %d\n", n);
1282                 p->setChannel(-1);
1283                 deallocateIsoChannel(isochannel);
1284                 return false;
1285             }
1286             if(reg_isoch != 0xFFFFFFFFUL) {
1287                 debugError("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08"PRIX32") for ATX %d\n", reg_isoch, n);
1288                 p->setChannel(-1);
1289                 deallocateIsoChannel(isochannel);
1290                 return false;
1291             }
1292    
1293             // write value of ISO_CHANNEL register
1294             reg_isoch = isochannel;
1295             if(!writeTxReg(n, DICE_REGISTER_TX_ISOC_BASE, reg_isoch)) {
1296                 debugError("Could not write ISO_CHANNEL register for ATX %d\n", n);
1297                 p->setChannel(-1);
1298                 deallocateIsoChannel(isochannel);
1299                 return false;
1300             }
1301         }
1302         return true;
1303
1304     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1305         int n=i-m_receiveProcessors.size();
1306         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1307
1308         if(snoopMode) { // a stream from the device to another host
1309             fb_quadlet_t reg_isoch;
1310             // check value of ISO_CHANNEL register
1311             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1312                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1313                 p->setChannel(-1);
1314                 return false;
1315             }
1316             int isochannel = reg_isoch;
1317             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Snooping TX from channel %d\n", this, isochannel);
1318             p->setChannel(isochannel);
1319         } else {
1320             // allocate ISO channel
1321             int isochannel = allocateIsoChannel(p->getMaxPacketSize());
1322             if(isochannel<0) {
1323                 debugError("Could not allocate iso channel for SP %d (ARX %d)\n",i,n);
1324                 return false;
1325             }
1326             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Allocated channel %u for TX\n", this, isochannel);
1327             p->setChannel(isochannel);
1328    
1329             fb_quadlet_t reg_isoch;
1330             // check value of ISO_CHANNEL register
1331             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1332                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1333                 p->setChannel(-1);
1334                 deallocateIsoChannel(isochannel);
1335                 return false;
1336             }
1337             if(reg_isoch != 0xFFFFFFFFUL) {
1338                 debugError("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08"PRIX32") for ARX %d\n", reg_isoch, n);
1339                 p->setChannel(-1);
1340                 deallocateIsoChannel(isochannel);
1341                 return false;
1342             }
1343    
1344             // write value of ISO_CHANNEL register
1345             reg_isoch=isochannel;
1346             if(!writeRxReg(n, DICE_REGISTER_RX_ISOC_BASE, reg_isoch)) {
1347                 debugError("Could not write ISO_CHANNEL register for ARX %d\n", n);
1348                 p->setChannel(-1);
1349                 deallocateIsoChannel(isochannel);
1350                 return false;
1351             }
1352         }
1353         return true;
1354     }
1355
1356     debugError("SP index %d out of range!\n",i);
1357     return false;
1358 }
1359
1360 bool
1361 Device::stopStreamByIndex(int i) {
1362     bool snoopMode = false;
1363     if(!getOption("snoopMode", snoopMode)) {
1364         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1365     }
1366
1367     if (!snoopMode && isIsoStreamingEnabled()) {
1368         debugError("Cannot stop streams while streaming is enabled\n");
1369         return false;
1370     }
1371
1372     if (i<(int)m_receiveProcessors.size()) {
1373         int n=i;
1374         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
1375         if(snoopMode) { // a stream from the device to another host
1376             // nothing to do
1377         } else {
1378             unsigned int isochannel = p->getChannel();
1379    
1380             fb_quadlet_t reg_isoch;
1381             // check value of ISO_CHANNEL register
1382             if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) {
1383                 debugError("Could not read ISO_CHANNEL register for ATX %d\n", n);
1384                 return false;
1385             }
1386             if(reg_isoch != isochannel) {
1387                 debugError("ISO_CHANNEL register != 0x%08"PRIX32" (=0x%08"PRIX32") for ATX %d\n", isochannel, reg_isoch, n);
1388                 return false;
1389             }
1390    
1391             // write value of ISO_CHANNEL register
1392             reg_isoch=0xFFFFFFFFUL;
1393             if(!writeTxReg(n, DICE_REGISTER_TX_ISOC_BASE, reg_isoch)) {
1394                 debugError("Could not write ISO_CHANNEL register for ATX %d\n", n);
1395                 return false;
1396             }
1397    
1398             // deallocate ISO channel
1399             if(!deallocateIsoChannel(isochannel)) {
1400                 debugError("Could not deallocate iso channel for SP %d (ATX %d)\n",i,n);
1401                 return false;
1402             }
1403         }
1404         p->setChannel(-1);
1405         return true;
1406
1407     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1408         int n=i-m_receiveProcessors.size();
1409         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1410
1411         if(snoopMode) { // a stream from the device to another host
1412             // nothing to do
1413         } else {
1414             unsigned int isochannel = p->getChannel();
1415    
1416             fb_quadlet_t reg_isoch;
1417             // check value of ISO_CHANNEL register
1418             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1419                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1420                 return false;
1421             }
1422             if(reg_isoch != isochannel) {
1423                 debugError("ISO_CHANNEL register != 0x%08"PRIX32" (=0x%08"PRIX32") for ARX %d\n", isochannel, reg_isoch, n);
1424                 return false;
1425             }
1426    
1427             // write value of ISO_CHANNEL register
1428             reg_isoch=0xFFFFFFFFUL;
1429             if(!writeRxReg(n, DICE_REGISTER_RX_ISOC_BASE, reg_isoch)) {
1430                 debugError("Could not write ISO_CHANNEL register for ARX %d\n", n);
1431                 return false;
1432             }
1433    
1434             // deallocate ISO channel
1435             if(!deallocateIsoChannel(isochannel)) {
1436                 debugError("Could not deallocate iso channel for SP %d (ARX %d)\n",i,n);
1437                 return false;
1438             }
1439         }
1440
1441         p->setChannel(-1);
1442         return true;
1443     }
1444
1445     debugError("SP index %d out of range!\n",i);
1446
1447     return false;
1448 }
1449
1450 // helper routines
1451
1452 // allocate ISO resources for the SP's
1453 int Device::allocateIsoChannel(unsigned int packet_size) {
1454     unsigned int bandwidth=8+packet_size;
1455
1456     int ch=get1394Service().allocateIsoChannelGeneric(bandwidth);
1457
1458     debugOutput(DEBUG_LEVEL_VERBOSE, "allocated channel %d, bandwidth %d\n",
1459         ch, bandwidth);
1460
1461     return ch;
1462 }
1463 // deallocate ISO resources
1464 bool Device::deallocateIsoChannel(int channel) {
1465     debugOutput(DEBUG_LEVEL_VERBOSE, "freeing channel %d\n",channel);
1466     return get1394Service().freeIsoChannel(channel);
1467 }
1468
1469 bool
1470 Device::enableIsoStreaming() {
1471     return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_ENABLE);
1472 }
1473
1474 bool
1475 Device::disableIsoStreaming() {
1476     return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_DISABLE);
1477 }
1478
1479 bool
1480 Device::isIsoStreamingEnabled() {
1481     fb_quadlet_t result;
1482     readGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, &result);
1483     // I don't know what exactly is 'enable',
1484     // but disable is definately == 0
1485     return (result != DICE_ISOSTREAMING_DISABLE);
1486 }
1487
1488 /**
1489  * @brief performs a masked bit register equals 0 check on the global parameter space
1490  * @return true if readGlobalReg(offset) & mask == 0
1491  */
1492 bool
1493 Device::maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) {
1494     fb_quadlet_t result;
1495     readGlobalReg(offset, &result);
1496     return ((result & mask) == 0);
1497 }
1498 /**
1499  * @brief performs a masked bit register not equal to 0 check on the global parameter space
1500  * @return true if readGlobalReg(offset) & mask != 0
1501  */
1502 bool
1503 Device::maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) {
1504     return !maskedCheckZeroGlobalReg(offset, mask);
1505 }
1506
1507 diceNameVector
1508 Device::getTxNameString(unsigned int i) {
1509     diceNameVector names;
1510     char namestring[DICE_TX_NAMES_SIZE+1];
1511
1512     if (!readTxRegBlock(i, DICE_REGISTER_TX_NAMES_BASE,
1513                         (fb_quadlet_t *)namestring, DICE_TX_NAMES_SIZE)) {
1514         debugError("Could not read TX name string \n");
1515         return names;
1516     }
1517
1518     // Strings from the device are always little-endian,
1519     // so byteswap for big-endian machines
1520     #if __BYTE_ORDER == __BIG_ENDIAN
1521     byteSwapBlock((quadlet_t *)namestring, DICE_TX_NAMES_SIZE/4);
1522     #endif
1523     namestring[DICE_TX_NAMES_SIZE]='\0';
1524     return splitNameString(std::string(namestring));
1525 }
1526
1527 diceNameVector
1528 Device::getRxNameString(unsigned int i) {
1529     diceNameVector names;
1530     char namestring[DICE_RX_NAMES_SIZE+1];
1531
1532     if (!readRxRegBlock(i, DICE_REGISTER_RX_NAMES_BASE,
1533                         (fb_quadlet_t *)namestring, DICE_RX_NAMES_SIZE)) {
1534         debugError("Could not read RX name string \n");
1535         return names;
1536     }
1537
1538     // Strings from the device are always little-endian,
1539     // so byteswap for big-endian machines
1540     #if __BYTE_ORDER == __BIG_ENDIAN
1541     byteSwapBlock((quadlet_t *)namestring, DICE_RX_NAMES_SIZE/4);
1542     #endif
1543     namestring[DICE_RX_NAMES_SIZE]='\0';
1544     return splitNameString(std::string(namestring));
1545 }
1546
1547 diceNameVector
1548 Device::getClockSourceNameString() {
1549     diceNameVector names;
1550     char namestring[DICE_CLOCKSOURCENAMES_SIZE+1];
1551
1552     if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_CLOCKSOURCENAMES,
1553                       (fb_quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE)) {
1554         debugError("Could not read CLOCKSOURCE name string \n");
1555         return names;
1556     }
1557
1558     // Strings from the device are always little-endian,
1559     // so byteswap for big-endian machines
1560     #if __BYTE_ORDER == __BIG_ENDIAN
1561     byteSwapBlock((quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE/4);
1562     #endif
1563     namestring[DICE_CLOCKSOURCENAMES_SIZE]='\0';
1564     return splitNameString(std::string(namestring));
1565 }
1566
1567 std::string
1568 Device::getDeviceNickName() {
1569     char namestring[DICE_NICK_NAME_SIZE+1];
1570
1571     if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_NICK_NAME,
1572                         (fb_quadlet_t *)namestring, DICE_NICK_NAME_SIZE)) {
1573         debugError("Could not read nickname string \n");
1574         return std::string("(unknown)");
1575     }
1576
1577     // Strings from the device are always little-endian,
1578     // so byteswap for big-endian machines
1579     #if __BYTE_ORDER == __BIG_ENDIAN
1580     byteSwapBlock((quadlet_t *)namestring, DICE_NICK_NAME_SIZE/4);
1581     #endif
1582     namestring[DICE_NICK_NAME_SIZE]='\0';
1583     return std::string(namestring);
1584 }
1585
1586 bool
1587 Device::setDeviceNickName(std::string name) {
1588     char namestring[DICE_NICK_NAME_SIZE+1];
1589     strncpy(namestring, name.c_str(), DICE_NICK_NAME_SIZE);
1590
1591     // Strings from the device are always little-endian,
1592     // so byteswap for big-endian machines
1593     #if __BYTE_ORDER == __BIG_ENDIAN
1594     byteSwapBlock((quadlet_t *)namestring, DICE_NICK_NAME_SIZE/4);
1595     #endif
1596
1597     if (!writeGlobalRegBlock(DICE_REGISTER_GLOBAL_NICK_NAME,
1598                         (fb_quadlet_t *)namestring, DICE_NICK_NAME_SIZE)) {
1599         debugError("Could not write nickname string \n");
1600         return false;
1601     }
1602     return true;
1603 }
1604
1605 diceNameVector
1606 Device::splitNameString(std::string in) {
1607     diceNameVector names;
1608
1609     // find the end of the string
1610     string::size_type end = in.find(string("\\\\"));
1611     // cut the end
1612     in = in.substr(0,end);
1613
1614     string::size_type cut;
1615     while( (cut = in.find(string("\\"))) != in.npos ) {
1616         if(cut > 0) {
1617             names.push_back(in.substr(0,cut));
1618         }
1619         in = in.substr(cut+1);
1620     }
1621     if(in.length() > 0) {
1622         names.push_back(in);
1623     }
1624     return names;
1625 }
1626
1627
1628 // I/O routines
1629 bool
1630 Device::initIoFunctions() {
1631
1632     // offsets and sizes are returned in quadlets, but we use byte values
1633     if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_OFF, &m_global_reg_offset)) {
1634         debugError("Could not initialize m_global_reg_offset\n");
1635         return false;
1636     }
1637     m_global_reg_offset*=4;
1638
1639     if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_SZ, &m_global_reg_size)) {
1640         debugError("Could not initialize m_global_reg_size\n");
1641         return false;
1642     }
1643     m_global_reg_size*=4;
1644
1645     if(!readReg(DICE_REGISTER_TX_PAR_SPACE_OFF, &m_tx_reg_offset)) {
1646         debugError("Could not initialize m_tx_reg_offset\n");
1647         return false;
1648     }
1649     m_tx_reg_offset*=4;
1650
1651     if(!readReg(DICE_REGISTER_TX_PAR_SPACE_SZ, &m_tx_reg_size)) {
1652         debugError("Could not initialize m_tx_reg_size\n");
1653         return false;
1654     }
1655     m_tx_reg_size*=4;
1656
1657     if(!readReg(DICE_REGISTER_RX_PAR_SPACE_OFF, &m_rx_reg_offset)) {
1658         debugError("Could not initialize m_rx_reg_offset\n");
1659         return false;
1660     }
1661     m_rx_reg_offset*=4;
1662
1663     if(!readReg(DICE_REGISTER_RX_PAR_SPACE_SZ, &m_rx_reg_size)) {
1664         debugError("Could not initialize m_rx_reg_size\n");
1665         return false;
1666     }
1667     m_rx_reg_size*=4;
1668
1669     if(!readReg(DICE_REGISTER_UNUSED1_SPACE_OFF, &m_unused1_reg_offset)) {
1670         debugError("Could not initialize m_unused1_reg_offset\n");
1671         return false;
1672     }
1673     m_unused1_reg_offset*=4;
1674
1675     if(!readReg(DICE_REGISTER_UNUSED1_SPACE_SZ, &m_unused1_reg_size)) {
1676         debugError("Could not initialize m_unused1_reg_size\n");
1677         return false;
1678     }
1679     m_unused1_reg_size*=4;
1680
1681     if(!readReg(DICE_REGISTER_UNUSED2_SPACE_OFF, &m_unused2_reg_offset)) {
1682         debugError("Could not initialize m_unused2_reg_offset\n");
1683         return false;
1684     }
1685     m_unused2_reg_offset*=4;
1686
1687     if(!readReg(DICE_REGISTER_UNUSED2_SPACE_SZ, &m_unused2_reg_size)) {
1688         debugError("Could not initialize m_unused2_reg_size\n");
1689         return false;
1690     }
1691     m_unused2_reg_size*=4;
1692
1693     if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_NB_TX, &m_nb_tx)) {
1694         debugError("Could not initialize m_nb_tx\n");
1695         return false;
1696     }
1697     if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_SZ_TX, &m_tx_size)) {
1698         debugError("Could not initialize m_tx_size\n");
1699         return false;
1700     }
1701     m_tx_size*=4;
1702
1703     if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_NB_RX, &m_nb_rx)) {
1704         debugError("Could not initialize m_nb_rx\n");
1705         return false;
1706     }
1707
1708     // FIXME: verify this and clean it up.
1709     /* special case for Alesis io14, which announces two receive transmitters,
1710      * but only has one. Same is true for Alesis Multimix16.
1711      */
1712     if (FW_VENDORID_ALESIS == getConfigRom().getNodeVendorId()) {
1713         /* we may want to use a switch-case-statement some day... */
1714         if ((0x00000001 == getConfigRom().getModelId()) ||
1715             (0x00000000 == getConfigRom().getModelId())) {
1716             m_nb_rx = 1;
1717         }
1718     }
1719
1720     if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_SZ_RX, &m_rx_size)) {
1721         debugError("Could not initialize m_rx_size\n");
1722         return false;
1723     }
1724     m_rx_size*=4;
1725
1726     debugOutput(DEBUG_LEVEL_VERBOSE,"DICE Parameter Space info:\n");
1727     debugOutput(DEBUG_LEVEL_VERBOSE," Global  : offset=%04X size=%04d\n", m_global_reg_offset, m_global_reg_size);
1728     debugOutput(DEBUG_LEVEL_VERBOSE," TX      : offset=%04X size=%04d\n", m_tx_reg_offset, m_tx_reg_size);
1729     debugOutput(DEBUG_LEVEL_VERBOSE,"               nb=%4d size=%04d\n", m_nb_tx, m_tx_size);
1730     debugOutput(DEBUG_LEVEL_VERBOSE," RX      : offset=%04X size=%04d\n", m_rx_reg_offset, m_rx_reg_size);
1731     debugOutput(DEBUG_LEVEL_VERBOSE,"               nb=%4d size=%04d\n", m_nb_rx, m_rx_size);
1732     debugOutput(DEBUG_LEVEL_VERBOSE," UNUSED1 : offset=%04X size=%04d\n", m_unused1_reg_offset, m_unused1_reg_size);
1733     debugOutput(DEBUG_LEVEL_VERBOSE," UNUSED2 : offset=%04X size=%04d\n", m_unused2_reg_offset, m_unused2_reg_size);
1734
1735     return true;
1736 }
1737
1738 bool
1739 Device::readReg(fb_nodeaddr_t offset, fb_quadlet_t *result) {
1740     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading base register offset 0x%08"PRIX64"\n", offset);
1741
1742     if(offset >= DICE_INVALID_OFFSET) {
1743         debugError("invalid offset: 0x%016"PRIX64"\n", offset);
1744         return false;
1745     }
1746
1747     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1748     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1749
1750     if(!get1394Service().read_quadlet( nodeId, addr, result ) ) {
1751         debugError("Could not read from node 0x%04X addr 0x%12"PRIX64"\n", nodeId, addr);
1752         return false;
1753     }
1754
1755     *result = CondSwapFromBus32(*result);
1756
1757     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Read result: 0x%08"PRIX32"\n", *result);
1758
1759     return true;
1760 }
1761
1762 bool
1763 Device::writeReg(fb_nodeaddr_t offset, fb_quadlet_t data) {
1764     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08"PRIX64", data: 0x%08"PRIX32"\n",
1765         offset, data);
1766
1767     if(offset >= DICE_INVALID_OFFSET) {
1768         debugError("invalid offset: 0x%012"PRIX64"\n", offset);
1769         return false;
1770     }
1771
1772     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1773     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1774
1775     if(!get1394Service().write_quadlet( nodeId, addr, CondSwapToBus32(data) ) ) {
1776         debugError("Could not write to node 0x%04X addr 0x%12"PRIX64"\n", nodeId, addr);
1777         return false;
1778     }
1779     return true;
1780 }
1781
1782 bool
1783 Device::readRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1784     debugOutput(DEBUG_LEVEL_VERBOSE,
1785                 "Reading base register offset 0x%08"PRIX64", length %zd, to %p\n",
1786                 offset, length, data);
1787     const int blocksize_quads = 512/4;
1788
1789     if(offset >= DICE_INVALID_OFFSET) {
1790         debugError("invalid offset: 0x%012"PRIX64"\n", offset);
1791         return false;
1792     }
1793
1794     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1795     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1796     int quads_done = 0;
1797     // round to next full quadlet
1798     int length_quads = (length+3)/4;
1799     while(quads_done < length_quads) {
1800         fb_nodeaddr_t curr_addr = addr + quads_done*4;
1801         fb_quadlet_t *curr_data = data + quads_done;
1802         int quads_todo = length_quads - quads_done;
1803         debugOutput(DEBUG_LEVEL_VERBOSE, "reading addr: 0x%012"PRIX64", %d quads to %p\n", curr_addr, quads_todo, curr_data);
1804        
1805         if (quads_todo > blocksize_quads) {
1806             debugOutput(DEBUG_LEVEL_VERBOSE, "Truncating read from %d to %d quadlets\n", quads_todo, blocksize_quads);
1807             quads_todo = blocksize_quads;
1808         }
1809         #ifdef DEBUG
1810         if (quads_todo < 0) {
1811             debugError("BUG: quads_todo < 0: %d\n", quads_todo);
1812         }
1813         #endif
1814
1815         if(!get1394Service().read( nodeId, curr_addr, quads_todo, curr_data ) ) {
1816             debugError("Could not read %d quadlets from node 0x%04X addr 0x%012"PRIX64"\n", quads_todo, nodeId, curr_addr);
1817             return false;
1818         }
1819         quads_done += quads_todo;
1820     }
1821
1822     byteSwapFromBus(data, length/4);
1823     return true;
1824 }
1825
1826 bool
1827 Device::writeRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1828     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08"PRIX64", length: %zd\n",
1829         offset, length);
1830     const int blocksize_quads = 512/4;
1831
1832     if(offset >= DICE_INVALID_OFFSET) {
1833         debugError("invalid offset: 0x%012"PRIX64"\n", offset);
1834         return false;
1835     }
1836
1837     fb_quadlet_t data_out[length/4];
1838     memcpy(data_out, data, length);
1839     byteSwapToBus(data_out, length/4);
1840
1841     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1842     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1843     int quads_done = 0;
1844     int length_quads = (length+3)/4;
1845     while(quads_done < length_quads) {
1846         fb_nodeaddr_t curr_addr = addr + quads_done*4;
1847         fb_quadlet_t *curr_data = data_out + quads_done;
1848         int quads_todo = length_quads - quads_done;
1849         if (quads_todo > blocksize_quads) {
1850             debugOutput(DEBUG_LEVEL_VERBOSE, "Truncating write from %d to %d quadlets\n", quads_todo, blocksize_quads);
1851             quads_todo = blocksize_quads;
1852         }
1853         #ifdef DEBUG
1854         if (quads_todo < 0) {
1855             debugError("BUG: quads_todo < 0: %d\n", quads_todo);
1856         }
1857         #endif
1858
1859         if(!get1394Service().write( nodeId, addr, quads_todo, curr_data ) ) {
1860             debugError("Could not write %d quadlets to node 0x%04X addr 0x%012"PRIX64"\n", quads_todo, nodeId, curr_addr);
1861             return false;
1862         }
1863         quads_done += quads_todo;
1864     }
1865
1866     return true;
1867 }
1868
1869 bool
1870 Device::readGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t *result) {
1871     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register offset 0x%04"PRIX64"\n", offset);
1872
1873     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, sizeof(fb_quadlet_t));
1874     return readReg(m_global_reg_offset + offset_gl, result);
1875 }
1876
1877 bool
1878 Device::writeGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t data) {
1879     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register offset 0x%08"PRIX64", data: 0x%08"PRIX32"\n",
1880         offset, data);
1881
1882     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, sizeof(fb_quadlet_t));
1883     return writeReg(m_global_reg_offset + offset_gl, data);
1884 }
1885
1886 bool
1887 Device::readGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1888     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register block offset 0x%04"PRIX64", length %zd bytes\n",
1889         offset, length);
1890
1891     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, length);
1892     return readRegBlock(m_global_reg_offset + offset_gl, data, length);
1893 }
1894
1895 bool
1896 Device::writeGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1897     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register block offset 0x%04"PRIX64", length: %zd bytes\n",
1898         offset, length);
1899
1900     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, length);
1901     return writeRegBlock(m_global_reg_offset + offset_gl, data, length);
1902 }
1903
1904 fb_nodeaddr_t
1905 Device::globalOffsetGen(fb_nodeaddr_t offset, size_t length) {
1906
1907     // registry offsets should always be smaller than 0x7FFFFFFF
1908     // because otherwise base + offset > 64bit
1909     if(m_global_reg_offset & 0x80000000) {
1910         debugError("register offset not initialized yet\n");
1911         return DICE_INVALID_OFFSET;
1912     }
1913     // out-of-range check
1914     if(offset+length > m_global_reg_offset+m_global_reg_size) {
1915         debugError("register offset+length too large: 0x%04"PRIX64"\n", offset + length);
1916         return DICE_INVALID_OFFSET;
1917     }
1918
1919     return offset;
1920 }
1921
1922 bool
1923 Device::readTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) {
1924     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Reading tx %d register offset 0x%04"PRIX64"\n", i, offset);
1925
1926     fb_nodeaddr_t offset_tx = txOffsetGen(i, offset, sizeof(fb_quadlet_t));
1927     return readReg(m_tx_reg_offset + offset_tx, result);
1928 }
1929
1930 bool
1931 Device::writeTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) {
1932     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing tx %d register offset 0x%08"PRIX64", data: 0x%08"PRIX32"\n",
1933         i, offset, data);
1934
1935     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, sizeof(fb_quadlet_t));
1936     return writeReg(m_tx_reg_offset + offset_tx, data);
1937 }
1938
1939 bool
1940 Device::readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1941     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04"PRIX64", length: %zd bytes\n",
1942         offset, length);
1943
1944     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length);
1945     return readRegBlock(m_tx_reg_offset + offset_tx, data, length);
1946 }
1947
1948 bool
1949 Device::writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1950     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04"PRIX64", length: %zd bytes\n",
1951         offset, length);
1952
1953     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length);
1954     return writeRegBlock(m_tx_reg_offset + offset_tx, data, length);
1955 }
1956
1957 fb_nodeaddr_t
1958 Device::txOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) {
1959     // registry offsets should always be smaller than 0x7FFFFFFF
1960     // because otherwise base + offset > 64bit
1961     if(m_tx_reg_offset & 0x80000000) {
1962         debugError("register offset not initialized yet\n");
1963         return DICE_INVALID_OFFSET;
1964     }
1965     if(m_nb_tx & 0x80000000) {
1966         debugError("m_nb_tx not initialized yet\n");
1967         return DICE_INVALID_OFFSET;
1968     }
1969     if(m_tx_size & 0x80000000) {
1970         debugError("m_tx_size not initialized yet\n");
1971         return DICE_INVALID_OFFSET;
1972     }
1973     if(i >= m_nb_tx) {
1974         debugError("TX index out of range\n");
1975         return DICE_INVALID_OFFSET;
1976     }
1977
1978     fb_nodeaddr_t offset_tx = DICE_REGISTER_TX_PARAM(m_tx_size, i, offset);
1979
1980     // out-of-range check
1981     if(offset_tx + length > m_tx_reg_offset+4+m_tx_reg_size*m_nb_tx) {
1982         debugError("register offset+length too large: 0x%04"PRIX64"\n", offset_tx + length);
1983         return DICE_INVALID_OFFSET;
1984     }
1985
1986     return offset_tx;
1987 }
1988
1989 bool
1990 Device::readRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) {
1991     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx %d register offset 0x%04"PRIX64"\n", i, offset);
1992
1993     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t));
1994     return readReg(m_rx_reg_offset + offset_rx, result);
1995 }
1996
1997 bool
1998 Device::writeRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) {
1999     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register offset 0x%08"PRIX64", data: 0x%08"PRIX32"\n",
2000         offset, data);
2001
2002     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t));
2003     return writeReg(m_rx_reg_offset + offset_rx, data);
2004 }
2005
2006 bool
2007 Device::readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
2008     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04"PRIX64", length: %zd bytes\n",
2009         offset, length);
2010
2011     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length);
2012     return readRegBlock(m_rx_reg_offset + offset_rx, data, length);
2013 }
2014
2015 bool
2016 Device::writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
2017     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04"PRIX64", length: %zd bytes\n",
2018         offset, length);
2019
2020     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length);
2021     return writeRegBlock(m_rx_reg_offset + offset_rx, data, length);
2022 }
2023
2024 fb_nodeaddr_t
2025 Device::rxOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) {
2026     // registry offsets should always be smaller than 0x7FFFFFFF
2027     // because otherwise base + offset > 64bit
2028     if(m_rx_reg_offset & 0x80000000) {
2029         debugError("register offset not initialized yet\n");
2030         return DICE_INVALID_OFFSET;
2031     }
2032     if(m_nb_rx & 0x80000000) {
2033         debugError("m_nb_rx not initialized yet\n");
2034         return DICE_INVALID_OFFSET;
2035     }
2036     if(m_rx_size & 0x80000000) {
2037         debugError("m_rx_size not initialized yet\n");
2038         return DICE_INVALID_OFFSET;
2039     }
2040     if(i >= m_nb_rx) {
2041         debugError("RX index out of range\n");
2042         return DICE_INVALID_OFFSET;
2043     }
2044
2045     fb_nodeaddr_t offset_rx = DICE_REGISTER_RX_PARAM(m_rx_size, i, offset);
2046
2047     // out-of-range check
2048     if(offset_rx + length > m_rx_reg_offset+4+m_rx_reg_size*m_nb_rx) {
2049         debugError("register offset+length too large: 0x%04"PRIX64"\n", offset_rx + length);
2050         return DICE_INVALID_OFFSET;
2051     }
2052     return offset_rx;
2053 }
2054
2055
2056 // the notifier
2057
2058 Device::Notifier::Notifier(Device &d, nodeaddr_t start)
2059  : ARMHandler(d.get1394Service(), start, DICE_NOTIFIER_BLOCK_LENGTH,
2060               RAW1394_ARM_READ | RAW1394_ARM_WRITE | RAW1394_ARM_LOCK,
2061               RAW1394_ARM_WRITE, 0)
2062  , m_device(d)
2063 {
2064     // switch over the debug module to that of this device instead of the 1394 service
2065     m_debugModule = d.m_debugModule;
2066 }
2067
2068 Device::Notifier::~Notifier()
2069 {
2070
2071 }
2072
2073 }
Note: See TracBrowser for help on using the browser.