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

Revision 2212, 68.8 kB (checked in by jwoithe, 12 years ago)

DICE: partially revert r2059 since device nicknames cannot be automatically retained across interface power cycles or resets. Owners of multiple identical devices would therefore have to manually reset the nicknames to avoid port name clashes. While a more robust solution is being devised, revert to the previous behaviour (the use of the GUID).

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