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

Revision 1727, 72.2 kB (checked in by arnonym, 14 years ago)

Introduce a virtual factory function. That way subclasses can have subclassed EAPs created. Like EAPs dealing with the special Focusrite extensions...

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 = Device::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 Device::EAP*
187 Device::createEAP() {
188     return new Device::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%08X, 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%08X, 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%08X, 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%08X, 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%08X, 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%08X, 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%016X\n",tmp_octlet);
613
614     readGlobalReg(DICE_REGISTER_GLOBAL_NOTIFICATION, &tmp_quadlet);
615     debugOutput(DEBUG_LEVEL_VERBOSE,"  Notification     : 0x%08X\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%08X\n",tmp_quadlet);
634
635     readGlobalReg(DICE_REGISTER_GLOBAL_SAMPLE_RATE, &tmp_quadlet);
636     debugOutput(DEBUG_LEVEL_NORMAL,"  Samplerate       : 0x%08X (%lu)\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%08X\n", tmp_quadlet);
640    
641     readGlobalReg(DICE_REGISTER_GLOBAL_VERSION, &tmp_quadlet);
642     debugOutput(DEBUG_LEVEL_NORMAL,"  Version          : 0x%08X (%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%08X\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%08X\n", tmp_quadlet);
680         readTxReg(i, DICE_REGISTER_TX_AC3_ENABLE_BASE, &tmp_quadlet);
681         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 enable        : 0x%08X\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%08X\n", tmp_quadlet);
710         readTxReg(i, DICE_REGISTER_RX_AC3_ENABLE_BASE, &tmp_quadlet);
711         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 enable        : 0x%08X\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%016llX\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, "(%p) Snooping RX from channel %d\n", isochannel);
1263             p->setChannel(isochannel);
1264         } else {
1265             // allocate ISO channel
1266             int isochannel = allocateIsoChannel(p->getMaxPacketSize());
1267             if(isochannel<0) {
1268                 debugError("Could not allocate iso channel for SP %d (ATX %d)\n",i,n);
1269                 return false;
1270             }
1271             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Allocated channel %lu for RX\n", isochannel);
1272             p->setChannel(isochannel);
1273    
1274             fb_quadlet_t reg_isoch;
1275             // check value of ISO_CHANNEL register
1276             if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) {
1277                 debugError("Could not read ISO_CHANNEL register for ATX %d\n", n);
1278                 p->setChannel(-1);
1279                 deallocateIsoChannel(isochannel);
1280                 return false;
1281             }
1282             if(reg_isoch != 0xFFFFFFFFUL) {
1283                 debugError("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08X) for ATX %d\n", reg_isoch, n);
1284                 p->setChannel(-1);
1285                 deallocateIsoChannel(isochannel);
1286                 return false;
1287             }
1288    
1289             // write value of ISO_CHANNEL register
1290             reg_isoch = isochannel;
1291             if(!writeTxReg(n, DICE_REGISTER_TX_ISOC_BASE, reg_isoch)) {
1292                 debugError("Could not write ISO_CHANNEL register for ATX %d\n", n);
1293                 p->setChannel(-1);
1294                 deallocateIsoChannel(isochannel);
1295                 return false;
1296             }
1297         }
1298         return true;
1299
1300     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1301         int n=i-m_receiveProcessors.size();
1302         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1303
1304         if(snoopMode) { // a stream from the device to another host
1305             fb_quadlet_t reg_isoch;
1306             // check value of ISO_CHANNEL register
1307             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1308                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1309                 p->setChannel(-1);
1310                 return false;
1311             }
1312             int isochannel = reg_isoch;
1313             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Snooping TX from channel %d\n", isochannel);
1314             p->setChannel(isochannel);
1315         } else {
1316             // allocate ISO channel
1317             int isochannel = allocateIsoChannel(p->getMaxPacketSize());
1318             if(isochannel<0) {
1319                 debugError("Could not allocate iso channel for SP %d (ARX %d)\n",i,n);
1320                 return false;
1321             }
1322             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Allocated channel %lu for TX\n", isochannel);
1323             p->setChannel(isochannel);
1324    
1325             fb_quadlet_t reg_isoch;
1326             // check value of ISO_CHANNEL register
1327             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1328                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1329                 p->setChannel(-1);
1330                 deallocateIsoChannel(isochannel);
1331                 return false;
1332             }
1333             if(reg_isoch != 0xFFFFFFFFUL) {
1334                 debugError("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08X) for ARX %d\n", reg_isoch, n);
1335                 p->setChannel(-1);
1336                 deallocateIsoChannel(isochannel);
1337                 return false;
1338             }
1339    
1340             // write value of ISO_CHANNEL register
1341             reg_isoch=isochannel;
1342             if(!writeRxReg(n, DICE_REGISTER_RX_ISOC_BASE, reg_isoch)) {
1343                 debugError("Could not write ISO_CHANNEL register for ARX %d\n", n);
1344                 p->setChannel(-1);
1345                 deallocateIsoChannel(isochannel);
1346                 return false;
1347             }
1348         }
1349         return true;
1350     }
1351
1352     debugError("SP index %d out of range!\n",i);
1353     return false;
1354 }
1355
1356 bool
1357 Device::stopStreamByIndex(int i) {
1358     bool snoopMode = false;
1359     if(!getOption("snoopMode", snoopMode)) {
1360         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1361     }
1362
1363     if (!snoopMode && isIsoStreamingEnabled()) {
1364         debugError("Cannot stop streams while streaming is enabled\n");
1365         return false;
1366     }
1367
1368     if (i<(int)m_receiveProcessors.size()) {
1369         int n=i;
1370         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
1371         if(snoopMode) { // a stream from the device to another host
1372             // nothing to do
1373         } else {
1374             unsigned int isochannel = p->getChannel();
1375    
1376             fb_quadlet_t reg_isoch;
1377             // check value of ISO_CHANNEL register
1378             if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) {
1379                 debugError("Could not read ISO_CHANNEL register for ATX %d\n", n);
1380                 return false;
1381             }
1382             if(reg_isoch != isochannel) {
1383                 debugError("ISO_CHANNEL register != 0x%08X (=0x%08X) for ATX %d\n", isochannel, reg_isoch, n);
1384                 return false;
1385             }
1386    
1387             // write value of ISO_CHANNEL register
1388             reg_isoch=0xFFFFFFFFUL;
1389             if(!writeTxReg(n, DICE_REGISTER_TX_ISOC_BASE, reg_isoch)) {
1390                 debugError("Could not write ISO_CHANNEL register for ATX %d\n", n);
1391                 return false;
1392             }
1393    
1394             // deallocate ISO channel
1395             if(!deallocateIsoChannel(isochannel)) {
1396                 debugError("Could not deallocate iso channel for SP %d (ATX %d)\n",i,n);
1397                 return false;
1398             }
1399         }
1400         p->setChannel(-1);
1401         return true;
1402
1403     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1404         int n=i-m_receiveProcessors.size();
1405         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1406
1407         if(snoopMode) { // a stream from the device to another host
1408             // nothing to do
1409         } else {
1410             unsigned int isochannel = p->getChannel();
1411    
1412             fb_quadlet_t reg_isoch;
1413             // check value of ISO_CHANNEL register
1414             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1415                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1416                 return false;
1417             }
1418             if(reg_isoch != isochannel) {
1419                 debugError("ISO_CHANNEL register != 0x%08X (=0x%08X) for ARX %d\n", isochannel, reg_isoch, n);
1420                 return false;
1421             }
1422    
1423             // write value of ISO_CHANNEL register
1424             reg_isoch=0xFFFFFFFFUL;
1425             if(!writeRxReg(n, DICE_REGISTER_RX_ISOC_BASE, reg_isoch)) {
1426                 debugError("Could not write ISO_CHANNEL register for ARX %d\n", n);
1427                 return false;
1428             }
1429    
1430             // deallocate ISO channel
1431             if(!deallocateIsoChannel(isochannel)) {
1432                 debugError("Could not deallocate iso channel for SP %d (ARX %d)\n",i,n);
1433                 return false;
1434             }
1435         }
1436
1437         p->setChannel(-1);
1438         return true;
1439     }
1440
1441     debugError("SP index %d out of range!\n",i);
1442
1443     return false;
1444 }
1445
1446 // helper routines
1447
1448 // allocate ISO resources for the SP's
1449 int Device::allocateIsoChannel(unsigned int packet_size) {
1450     unsigned int bandwidth=8+packet_size;
1451
1452     int ch=get1394Service().allocateIsoChannelGeneric(bandwidth);
1453
1454     debugOutput(DEBUG_LEVEL_VERBOSE, "allocated channel %d, bandwidth %d\n",
1455         ch, bandwidth);
1456
1457     return ch;
1458 }
1459 // deallocate ISO resources
1460 bool Device::deallocateIsoChannel(int channel) {
1461     debugOutput(DEBUG_LEVEL_VERBOSE, "freeing channel %d\n",channel);
1462     return get1394Service().freeIsoChannel(channel);
1463 }
1464
1465 bool
1466 Device::enableIsoStreaming() {
1467     return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_ENABLE);
1468 }
1469
1470 bool
1471 Device::disableIsoStreaming() {
1472     return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_DISABLE);
1473 }
1474
1475 bool
1476 Device::isIsoStreamingEnabled() {
1477     fb_quadlet_t result;
1478     readGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, &result);
1479     // I don't know what exactly is 'enable',
1480     // but disable is definately == 0
1481     return (result != DICE_ISOSTREAMING_DISABLE);
1482 }
1483
1484 /**
1485  * @brief performs a masked bit register equals 0 check on the global parameter space
1486  * @return true if readGlobalReg(offset) & mask == 0
1487  */
1488 bool
1489 Device::maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) {
1490     fb_quadlet_t result;
1491     readGlobalReg(offset, &result);
1492     return ((result & mask) == 0);
1493 }
1494 /**
1495  * @brief performs a masked bit register not equal to 0 check on the global parameter space
1496  * @return true if readGlobalReg(offset) & mask != 0
1497  */
1498 bool
1499 Device::maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) {
1500     return !maskedCheckZeroGlobalReg(offset, mask);
1501 }
1502
1503 Device::diceNameVector
1504 Device::getTxNameString(unsigned int i) {
1505     diceNameVector names;
1506     char namestring[DICE_TX_NAMES_SIZE+1];
1507
1508     if (!readTxRegBlock(i, DICE_REGISTER_TX_NAMES_BASE,
1509                         (fb_quadlet_t *)namestring, DICE_TX_NAMES_SIZE)) {
1510         debugError("Could not read TX name string \n");
1511         return names;
1512     }
1513
1514     // Strings from the device are always little-endian,
1515     // so byteswap for big-endian machines
1516     #if __BYTE_ORDER == __BIG_ENDIAN
1517     byteSwapBlock((quadlet_t *)namestring, DICE_TX_NAMES_SIZE/4);
1518     #endif
1519     namestring[DICE_TX_NAMES_SIZE]='\0';
1520     return splitNameString(std::string(namestring));
1521 }
1522
1523 Device::diceNameVector
1524 Device::getRxNameString(unsigned int i) {
1525     diceNameVector names;
1526     char namestring[DICE_RX_NAMES_SIZE+1];
1527
1528     if (!readRxRegBlock(i, DICE_REGISTER_RX_NAMES_BASE,
1529                         (fb_quadlet_t *)namestring, DICE_RX_NAMES_SIZE)) {
1530         debugError("Could not read RX name string \n");
1531         return names;
1532     }
1533
1534     // Strings from the device are always little-endian,
1535     // so byteswap for big-endian machines
1536     #if __BYTE_ORDER == __BIG_ENDIAN
1537     byteSwapBlock((quadlet_t *)namestring, DICE_RX_NAMES_SIZE/4);
1538     #endif
1539     namestring[DICE_RX_NAMES_SIZE]='\0';
1540     return splitNameString(std::string(namestring));
1541 }
1542
1543 Device::diceNameVector
1544 Device::getClockSourceNameString() {
1545     diceNameVector names;
1546     char namestring[DICE_CLOCKSOURCENAMES_SIZE+1];
1547
1548     if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_CLOCKSOURCENAMES,
1549                       (fb_quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE)) {
1550         debugError("Could not read CLOCKSOURCE name string \n");
1551         return names;
1552     }
1553
1554     // Strings from the device are always little-endian,
1555     // so byteswap for big-endian machines
1556     #if __BYTE_ORDER == __BIG_ENDIAN
1557     byteSwapBlock((quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE/4);
1558     #endif
1559     namestring[DICE_CLOCKSOURCENAMES_SIZE]='\0';
1560     return splitNameString(std::string(namestring));
1561 }
1562
1563 std::string
1564 Device::getDeviceNickName() {
1565     char namestring[DICE_NICK_NAME_SIZE+1];
1566
1567     if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_NICK_NAME,
1568                         (fb_quadlet_t *)namestring, DICE_NICK_NAME_SIZE)) {
1569         debugError("Could not read nickname string \n");
1570         return std::string("(unknown)");
1571     }
1572
1573     // Strings from the device are always little-endian,
1574     // so byteswap for big-endian machines
1575     #if __BYTE_ORDER == __BIG_ENDIAN
1576     byteSwapBlock((quadlet_t *)namestring, DICE_NICK_NAME_SIZE/4);
1577     #endif
1578     namestring[DICE_NICK_NAME_SIZE]='\0';
1579     return std::string(namestring);
1580 }
1581
1582 bool
1583 Device::setDeviceNickName(std::string name) {
1584     char namestring[DICE_NICK_NAME_SIZE+1];
1585     strncpy(namestring, name.c_str(), DICE_NICK_NAME_SIZE);
1586
1587     // Strings from the device are always little-endian,
1588     // so byteswap for big-endian machines
1589     #if __BYTE_ORDER == __BIG_ENDIAN
1590     byteSwapBlock((quadlet_t *)namestring, DICE_NICK_NAME_SIZE/4);
1591     #endif
1592
1593     if (!writeGlobalRegBlock(DICE_REGISTER_GLOBAL_NICK_NAME,
1594                         (fb_quadlet_t *)namestring, DICE_NICK_NAME_SIZE)) {
1595         debugError("Could not write nickname string \n");
1596         return false;
1597     }
1598     return true;
1599 }
1600
1601 Device::diceNameVector
1602 Device::splitNameString(std::string in) {
1603     diceNameVector names;
1604
1605     // find the end of the string
1606     string::size_type end = in.find(string("\\\\"));
1607     // cut the end
1608     in = in.substr(0,end);
1609
1610     string::size_type cut;
1611     while( (cut = in.find(string("\\"))) != in.npos ) {
1612         if(cut > 0) {
1613             names.push_back(in.substr(0,cut));
1614         }
1615         in = in.substr(cut+1);
1616     }
1617     if(in.length() > 0) {
1618         names.push_back(in);
1619     }
1620     return names;
1621 }
1622
1623
1624 // I/O routines
1625 bool
1626 Device::initIoFunctions() {
1627
1628     // offsets and sizes are returned in quadlets, but we use byte values
1629     if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_OFF, &m_global_reg_offset)) {
1630         debugError("Could not initialize m_global_reg_offset\n");
1631         return false;
1632     }
1633     m_global_reg_offset*=4;
1634
1635     if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_SZ, &m_global_reg_size)) {
1636         debugError("Could not initialize m_global_reg_size\n");
1637         return false;
1638     }
1639     m_global_reg_size*=4;
1640
1641     if(!readReg(DICE_REGISTER_TX_PAR_SPACE_OFF, &m_tx_reg_offset)) {
1642         debugError("Could not initialize m_tx_reg_offset\n");
1643         return false;
1644     }
1645     m_tx_reg_offset*=4;
1646
1647     if(!readReg(DICE_REGISTER_TX_PAR_SPACE_SZ, &m_tx_reg_size)) {
1648         debugError("Could not initialize m_tx_reg_size\n");
1649         return false;
1650     }
1651     m_tx_reg_size*=4;
1652
1653     if(!readReg(DICE_REGISTER_RX_PAR_SPACE_OFF, &m_rx_reg_offset)) {
1654         debugError("Could not initialize m_rx_reg_offset\n");
1655         return false;
1656     }
1657     m_rx_reg_offset*=4;
1658
1659     if(!readReg(DICE_REGISTER_RX_PAR_SPACE_SZ, &m_rx_reg_size)) {
1660         debugError("Could not initialize m_rx_reg_size\n");
1661         return false;
1662     }
1663     m_rx_reg_size*=4;
1664
1665     if(!readReg(DICE_REGISTER_UNUSED1_SPACE_OFF, &m_unused1_reg_offset)) {
1666         debugError("Could not initialize m_unused1_reg_offset\n");
1667         return false;
1668     }
1669     m_unused1_reg_offset*=4;
1670
1671     if(!readReg(DICE_REGISTER_UNUSED1_SPACE_SZ, &m_unused1_reg_size)) {
1672         debugError("Could not initialize m_unused1_reg_size\n");
1673         return false;
1674     }
1675     m_unused1_reg_size*=4;
1676
1677     if(!readReg(DICE_REGISTER_UNUSED2_SPACE_OFF, &m_unused2_reg_offset)) {
1678         debugError("Could not initialize m_unused2_reg_offset\n");
1679         return false;
1680     }
1681     m_unused2_reg_offset*=4;
1682
1683     if(!readReg(DICE_REGISTER_UNUSED2_SPACE_SZ, &m_unused2_reg_size)) {
1684         debugError("Could not initialize m_unused2_reg_size\n");
1685         return false;
1686     }
1687     m_unused2_reg_size*=4;
1688
1689     if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_NB_TX, &m_nb_tx)) {
1690         debugError("Could not initialize m_nb_tx\n");
1691         return false;
1692     }
1693     if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_SZ_TX, &m_tx_size)) {
1694         debugError("Could not initialize m_tx_size\n");
1695         return false;
1696     }
1697     m_tx_size*=4;
1698
1699     if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_NB_RX, &m_nb_rx)) {
1700         debugError("Could not initialize m_nb_rx\n");
1701         return false;
1702     }
1703
1704     // FIXME: verify this and clean it up.
1705     /* special case for Alesis io14, which announces two receive transmitters,
1706      * but only has one. Same is true for Alesis Multimix16.
1707      */
1708     if (FW_VENDORID_ALESIS == getConfigRom().getNodeVendorId()) {
1709         /* we may want to use a switch-case-statement some day... */
1710         if ((0x00000001 == getConfigRom().getModelId()) ||
1711             (0x00000000 == getConfigRom().getModelId())) {
1712             m_nb_rx = 1;
1713         }
1714     }
1715
1716     if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_SZ_RX, &m_rx_size)) {
1717         debugError("Could not initialize m_rx_size\n");
1718         return false;
1719     }
1720     m_rx_size*=4;
1721
1722     debugOutput(DEBUG_LEVEL_VERBOSE,"DICE Parameter Space info:\n");
1723     debugOutput(DEBUG_LEVEL_VERBOSE," Global  : offset=%04X size=%04d\n", m_global_reg_offset, m_global_reg_size);
1724     debugOutput(DEBUG_LEVEL_VERBOSE," TX      : offset=%04X size=%04d\n", m_tx_reg_offset, m_tx_reg_size);
1725     debugOutput(DEBUG_LEVEL_VERBOSE,"               nb=%4d size=%04d\n", m_nb_tx, m_tx_size);
1726     debugOutput(DEBUG_LEVEL_VERBOSE," RX      : offset=%04X size=%04d\n", m_rx_reg_offset, m_rx_reg_size);
1727     debugOutput(DEBUG_LEVEL_VERBOSE,"               nb=%4d size=%04d\n", m_nb_rx, m_rx_size);
1728     debugOutput(DEBUG_LEVEL_VERBOSE," UNUSED1 : offset=%04X size=%04d\n", m_unused1_reg_offset, m_unused1_reg_size);
1729     debugOutput(DEBUG_LEVEL_VERBOSE," UNUSED2 : offset=%04X size=%04d\n", m_unused2_reg_offset, m_unused2_reg_size);
1730
1731     return true;
1732 }
1733
1734 bool
1735 Device::readReg(fb_nodeaddr_t offset, fb_quadlet_t *result) {
1736     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading base register offset 0x%08llX\n", offset);
1737
1738     if(offset >= DICE_INVALID_OFFSET) {
1739         debugError("invalid offset: 0x%016llX\n", offset);
1740         return false;
1741     }
1742
1743     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1744     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1745
1746     if(!get1394Service().read_quadlet( nodeId, addr, result ) ) {
1747         debugError("Could not read from node 0x%04X addr 0x%012X\n", nodeId, addr);
1748         return false;
1749     }
1750
1751     *result = CondSwapFromBus32(*result);
1752
1753     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Read result: 0x%08X\n", *result);
1754
1755     return true;
1756 }
1757
1758 bool
1759 Device::writeReg(fb_nodeaddr_t offset, fb_quadlet_t data) {
1760     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08llX, data: 0x%08X\n",
1761         offset, data);
1762
1763     if(offset >= DICE_INVALID_OFFSET) {
1764         debugError("invalid offset: 0x%016llX\n", offset);
1765         return false;
1766     }
1767
1768     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1769     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1770
1771     if(!get1394Service().write_quadlet( nodeId, addr, CondSwapToBus32(data) ) ) {
1772         debugError("Could not write to node 0x%04X addr 0x%012X\n", nodeId, addr);
1773         return false;
1774     }
1775     return true;
1776 }
1777
1778 bool
1779 Device::readRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1780     debugOutput(DEBUG_LEVEL_VERBOSE,"Reading base register offset 0x%08llX, length %u, to %p\n",
1781         offset, length, data);
1782     const int blocksize_quads = 512/4;
1783
1784     if(offset >= DICE_INVALID_OFFSET) {
1785         debugError("invalid offset: 0x%016llX\n", offset);
1786         return false;
1787     }
1788
1789     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1790     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1791     int quads_done = 0;
1792     // round to next full quadlet
1793     int length_quads = (length+3)/4;
1794     while(quads_done < length_quads) {
1795         fb_nodeaddr_t curr_addr = addr + quads_done*4;
1796         fb_quadlet_t *curr_data = data + quads_done;
1797         int quads_todo = length_quads - quads_done;
1798         debugOutput(DEBUG_LEVEL_VERBOSE, "reading addr: 0x%016llX, %d quads to %p\n", curr_addr, quads_todo, curr_data);
1799        
1800         if (quads_todo > blocksize_quads) {
1801             debugOutput(DEBUG_LEVEL_VERBOSE, "Truncating read from %d to %d quadlets\n", quads_todo, blocksize_quads);
1802             quads_todo = blocksize_quads;
1803         }
1804         #ifdef DEBUG
1805         if (quads_todo < 0) {
1806             debugError("BUG: quads_todo < 0: %d\n", quads_todo);
1807         }
1808         #endif
1809
1810         if(!get1394Service().read( nodeId, curr_addr, quads_todo, curr_data ) ) {
1811             debugError("Could not read %d quadlets from node 0x%04X addr 0x%012llX\n", quads_todo, nodeId, curr_addr);
1812             return false;
1813         }
1814         quads_done += quads_todo;
1815     }
1816
1817     byteSwapFromBus(data, length/4);
1818     return true;
1819 }
1820
1821 bool
1822 Device::writeRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1823     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08llX, length: %u\n",
1824         offset, length);
1825     const int blocksize_quads = 512/4;
1826
1827     if(offset >= DICE_INVALID_OFFSET) {
1828         debugError("invalid offset: 0x%016llX\n", offset);
1829         return false;
1830     }
1831
1832     fb_quadlet_t data_out[length/4];
1833     memcpy(data_out, data, length);
1834     byteSwapToBus(data_out, length/4);
1835
1836     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1837     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1838     int quads_done = 0;
1839     int length_quads = (length+3)/4;
1840     while(quads_done < length_quads) {
1841         fb_nodeaddr_t curr_addr = addr + quads_done*4;
1842         fb_quadlet_t *curr_data = data_out + quads_done;
1843         int quads_todo = length_quads - quads_done;
1844         if (quads_todo > blocksize_quads) {
1845             debugOutput(DEBUG_LEVEL_VERBOSE, "Truncating write from %d to %d quadlets\n", quads_todo, blocksize_quads);
1846             quads_todo = blocksize_quads;
1847         }
1848         #ifdef DEBUG
1849         if (quads_todo < 0) {
1850             debugError("BUG: quads_todo < 0: %d\n", quads_todo);
1851         }
1852         #endif
1853
1854         if(!get1394Service().write( nodeId, addr, quads_todo, curr_data ) ) {
1855             debugError("Could not write %d quadlets to node 0x%04X addr 0x%012llX\n", quads_todo, nodeId, curr_addr);
1856             return false;
1857         }
1858         quads_done += quads_todo;
1859     }
1860
1861     return true;
1862 }
1863
1864 bool
1865 Device::readGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t *result) {
1866     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register offset 0x%04llX\n", offset);
1867
1868     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, sizeof(fb_quadlet_t));
1869     return readReg(m_global_reg_offset + offset_gl, result);
1870 }
1871
1872 bool
1873 Device::writeGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t data) {
1874     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register offset 0x%08llX, data: 0x%08X\n",
1875         offset, data);
1876
1877     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, sizeof(fb_quadlet_t));
1878     return writeReg(m_global_reg_offset + offset_gl, data);
1879 }
1880
1881 bool
1882 Device::readGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1883     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register block offset 0x%04llX, length %u bytes\n",
1884         offset, length);
1885
1886     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, length);
1887     return readRegBlock(m_global_reg_offset + offset_gl, data, length);
1888 }
1889
1890 bool
1891 Device::writeGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1892     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register block offset 0x%04llX, length %u bytes\n",
1893         offset, length);
1894
1895     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, length);
1896     return writeRegBlock(m_global_reg_offset + offset_gl, data, length);
1897 }
1898
1899 fb_nodeaddr_t
1900 Device::globalOffsetGen(fb_nodeaddr_t offset, size_t length) {
1901
1902     // registry offsets should always be smaller than 0x7FFFFFFF
1903     // because otherwise base + offset > 64bit
1904     if(m_global_reg_offset & 0x80000000) {
1905         debugError("register offset not initialized yet\n");
1906         return DICE_INVALID_OFFSET;
1907     }
1908     // out-of-range check
1909     if(offset+length > m_global_reg_offset+m_global_reg_size) {
1910         debugError("register offset+length too large: 0x%0llX\n", offset + length);
1911         return DICE_INVALID_OFFSET;
1912     }
1913
1914     return offset;
1915 }
1916
1917 bool
1918 Device::readTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) {
1919     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Reading tx %d register offset 0x%04llX\n", i, offset);
1920
1921     fb_nodeaddr_t offset_tx = txOffsetGen(i, offset, sizeof(fb_quadlet_t));
1922     return readReg(m_tx_reg_offset + offset_tx, result);
1923 }
1924
1925 bool
1926 Device::writeTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) {
1927     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing tx %d register offset 0x%08llX, data: 0x%08X\n",
1928         i, offset, data);
1929
1930     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, sizeof(fb_quadlet_t));
1931     return writeReg(m_tx_reg_offset + offset_tx, data);
1932 }
1933
1934 bool
1935 Device::readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1936     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04llX, length %u bytes\n",
1937         offset, length);
1938
1939     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length);
1940     return readRegBlock(m_tx_reg_offset + offset_tx, data, length);
1941 }
1942
1943 bool
1944 Device::writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1945     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04llX, length %u bytes\n",
1946         offset, length);
1947
1948     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length);
1949     return writeRegBlock(m_tx_reg_offset + offset_tx, data, length);
1950 }
1951
1952 fb_nodeaddr_t
1953 Device::txOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) {
1954     // registry offsets should always be smaller than 0x7FFFFFFF
1955     // because otherwise base + offset > 64bit
1956     if(m_tx_reg_offset & 0x80000000) {
1957         debugError("register offset not initialized yet\n");
1958         return DICE_INVALID_OFFSET;
1959     }
1960     if(m_nb_tx & 0x80000000) {
1961         debugError("m_nb_tx not initialized yet\n");
1962         return DICE_INVALID_OFFSET;
1963     }
1964     if(m_tx_size & 0x80000000) {
1965         debugError("m_tx_size not initialized yet\n");
1966         return DICE_INVALID_OFFSET;
1967     }
1968     if(i >= m_nb_tx) {
1969         debugError("TX index out of range\n");
1970         return DICE_INVALID_OFFSET;
1971     }
1972
1973     fb_nodeaddr_t offset_tx = DICE_REGISTER_TX_PARAM(m_tx_size, i, offset);
1974
1975     // out-of-range check
1976     if(offset_tx + length > m_tx_reg_offset+4+m_tx_reg_size*m_nb_tx) {
1977         debugError("register offset+length too large: 0x%0llX\n", offset_tx + length);
1978         return DICE_INVALID_OFFSET;
1979     }
1980
1981     return offset_tx;
1982 }
1983
1984 bool
1985 Device::readRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) {
1986     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx %d register offset 0x%04llX\n", i, offset);
1987
1988     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t));
1989     return readReg(m_rx_reg_offset + offset_rx, result);
1990 }
1991
1992 bool
1993 Device::writeRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) {
1994     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register offset 0x%08llX, data: 0x%08X\n",
1995         offset, data);
1996
1997     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t));
1998     return writeReg(m_rx_reg_offset + offset_rx, data);
1999 }
2000
2001 bool
2002 Device::readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
2003     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04llX, length %u bytes\n",
2004         offset, length);
2005
2006     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length);
2007     return readRegBlock(m_rx_reg_offset + offset_rx, data, length);
2008 }
2009
2010 bool
2011 Device::writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
2012     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04llX, length %u bytes\n",
2013         offset, length);
2014
2015     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length);
2016     return writeRegBlock(m_rx_reg_offset + offset_rx, data, length);
2017 }
2018
2019 fb_nodeaddr_t
2020 Device::rxOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) {
2021     // registry offsets should always be smaller than 0x7FFFFFFF
2022     // because otherwise base + offset > 64bit
2023     if(m_rx_reg_offset & 0x80000000) {
2024         debugError("register offset not initialized yet\n");
2025         return DICE_INVALID_OFFSET;
2026     }
2027     if(m_nb_rx & 0x80000000) {
2028         debugError("m_nb_rx not initialized yet\n");
2029         return DICE_INVALID_OFFSET;
2030     }
2031     if(m_rx_size & 0x80000000) {
2032         debugError("m_rx_size not initialized yet\n");
2033         return DICE_INVALID_OFFSET;
2034     }
2035     if(i >= m_nb_rx) {
2036         debugError("RX index out of range\n");
2037         return DICE_INVALID_OFFSET;
2038     }
2039
2040     fb_nodeaddr_t offset_rx = DICE_REGISTER_RX_PARAM(m_rx_size, i, offset);
2041
2042     // out-of-range check
2043     if(offset_rx + length > m_rx_reg_offset+4+m_rx_reg_size*m_nb_rx) {
2044         debugError("register offset+length too large: 0x%0llX\n", offset_rx + length);
2045         return DICE_INVALID_OFFSET;
2046     }
2047     return offset_rx;
2048 }
2049
2050
2051 // the notifier
2052
2053 Device::Notifier::Notifier(Device &d, nodeaddr_t start)
2054  : ARMHandler(d.get1394Service(), start, DICE_NOTIFIER_BLOCK_LENGTH,
2055               RAW1394_ARM_READ | RAW1394_ARM_WRITE | RAW1394_ARM_LOCK,
2056               RAW1394_ARM_WRITE, 0)
2057  , m_device(d)
2058 {
2059     // switch over the debug module to that of this device instead of the 1394 service
2060     m_debugModule = d.m_debugModule;
2061 }
2062
2063 Device::Notifier::~Notifier()
2064 {
2065
2066 }
2067
2068 }
Note: See TracBrowser for help on using the browser.