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

Revision 1815, 71.0 kB (checked in by arnonym, 14 years ago)

Looks as if the DSP-version has the 0x08 as id.

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