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

Revision 2161, 67.8 kB (checked in by adi, 12 years ago)

DICE: Ignore streaming status

Before, ffado refused to do anything if streaming was enabled. I don't
see the rationale behind, so let's disable the checks.

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         debugWarning("The audio channel name vector is incorrect, using default names\n");
872         names_audio.clear();
873
874         for (unsigned int j=0;j<nb_audio;j++) {
875             std::ostringstream newname;
876             newname << "input_" << j;
877             names_audio.push_back(newname.str());
878         }
879     }
880
881     nb_channels = nb_audio;
882     if(nb_midi) nb_channels += 1; // midi-muxed counts as one
883
884     // construct the MIDI names
885     for (unsigned int j=0;j<nb_midi;j++) {
886         std::ostringstream newname;
887         newname << "midi " << j;
888         names_midi.push_back(newname.str());
889     }
890
891     // construct the streamprocessor
892     if (direction == Streaming::Port::E_Capture || snoopMode) {
893         p = new Streaming::AmdtpReceiveStreamProcessor(*this, nb_channels);
894         dll_bw = recv_sp_dll_bw;
895         direction = Streaming::Port::E_Capture;
896     } else {
897         p = new Streaming::AmdtpTransmitStreamProcessor(*this, nb_channels);
898         dll_bw = xmit_sp_dll_bw;
899
900 #if AMDTP_ALLOW_PAYLOAD_IN_NODATA_XMIT
901         // the DICE-II cannot handle payload in the NO-DATA packets.
902         // the other DICE chips don't need payload. Therefore
903         // we disable it.
904         ((Streaming::AmdtpTransmitStreamProcessor*)p)->sendPayloadForNoDataPackets(false);
905 #endif
906
907         // transmit control parameters
908         ((Streaming::AmdtpTransmitStreamProcessor*)p)->setMaxCyclesToTransmitEarly(xmit_max_cycles_early_transmit);
909         ((Streaming::AmdtpTransmitStreamProcessor*)p)->setTransferDelay(xmit_transfer_delay);
910         ((Streaming::AmdtpTransmitStreamProcessor*)p)->setMinCyclesBeforePresentation(xmit_min_cycles_before_presentation);
911     }
912
913
914     if(!p->init()) {
915         debugFatal("Could not initialize %s processor!\n", dir);
916         delete p;
917         // non-fatal error, simply returning true. Only false is important for prepare();
918         return true;
919     }
920
921     // add audio ports to the processor
922     for (unsigned int j=0;j<nb_audio;j++) {
923         diceChannelInfo channelInfo;
924         channelInfo.name=names_audio.at(j);
925         channelInfo.portType=ePT_Analog;
926         channelInfo.streamPosition=j;
927         channelInfo.streamLocation=0;
928
929         if (!addChannelToProcessor(&channelInfo, p, direction)) {
930             debugError("Could not add channel %s to StreamProcessor\n",
931                     channelInfo.name.c_str());
932             continue;
933         }
934     }
935
936     // add midi ports to the processor
937     for (unsigned int j=0;j<nb_midi;j++) {
938         diceChannelInfo channelInfo;
939         channelInfo.name=names_midi.at(j);
940         channelInfo.portType=ePT_MIDI;
941         channelInfo.streamPosition=nb_audio;
942         channelInfo.streamLocation=j;
943
944         if (!addChannelToProcessor(&channelInfo, p, direction)) {
945             debugError("Could not add channel %s to StreamProcessor\n",
946                     channelInfo.name.c_str());
947             continue;
948         }
949     }
950
951     if(!p->setDllBandwidth(dll_bw)) {
952         debugFatal("Could not set DLL bandwidth\n");
953         delete p;
954         return false;
955     }
956
957     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) %s SP on channel [%d audio, %d midi]\n",
958             this, dir, nb_audio, nb_midi);
959     // add the SP to the vector
960     if (direction_requested == Streaming::Port::E_Capture) {
961         m_receiveProcessors.push_back(p);
962     } else {
963         // we put this SP into the transmit SP vector,
964         // no matter if we are in snoop mode or not
965         // this allows us to find out what direction
966         // a certain stream should have.
967         m_transmitProcessors.push_back(p);
968     }
969
970     return true;
971 }
972
973 // NOTE on bandwidth calculation
974 // FIXME: The bandwidth allocation calculation can probably be
975 // refined somewhat since this is currently based on a rudimentary
976 // understanding of the iso protocol.
977 // Currently we assume the following.
978 //   * Ack/iso gap = 0.05 us
979 //   * DATA_PREFIX = 0.16 us1
980 //   * DATA_END    = 0.26 us
981 // These numbers are the worst-case figures given in the ieee1394
982 // standard.  This gives approximately 0.5 us of overheads per
983 // packet - around 25 bandwidth allocation units (from the ieee1394
984 // standard 1 bandwidth allocation unit is 125/6144 us).  We further
985 // assume the device is running at S400 (which it should be) so one
986 // allocation unit is equivalent to 1 transmitted byte; thus the
987 // bandwidth allocation required for the packets themselves is just
988 // the size of the packet.
989 bool
990 Device::prepare() {
991
992     bool exit_code = true;
993
994     // prepare receive SP's
995     for (unsigned int i=0; i<m_nb_tx; i++) {
996         exit_code &= prepareSP (i, Streaming::Port::E_Capture);
997     }
998
999     for (unsigned int i=0; i<m_nb_rx; i++) {
1000         exit_code &= prepareSP (i, Streaming::Port::E_Playback);
1001     }
1002
1003     return exit_code;
1004 }
1005
1006 bool
1007 Device::addChannelToProcessor(
1008     diceChannelInfo *channelInfo,
1009     Streaming::StreamProcessor *processor,
1010     Streaming::Port::E_Direction direction) {
1011     std::string dev_name;
1012
1013     std::string id=std::string("dev?");
1014     dev_name = getNickname();
1015     if(!getOption("id", id) && dev_name.size() == 0) {
1016         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
1017     }
1018
1019     if (dev_name.size() == 0) dev_name = id;
1020     std::ostringstream portname;
1021     portname << dev_name << "/" << channelInfo->name;
1022
1023     Streaming::Port *p=NULL;
1024     switch(channelInfo->portType) {
1025     case ePT_Analog:
1026         p=new Streaming::AmdtpAudioPort(
1027                 *processor,
1028                 portname.str(),
1029                 direction,
1030                 channelInfo->streamPosition,
1031                 channelInfo->streamLocation,
1032                 Streaming::AmdtpPortInfo::E_MBLA
1033         );
1034         break;
1035
1036     case ePT_MIDI:
1037         p=new Streaming::AmdtpMidiPort(
1038                 *processor,
1039                 portname.str(),
1040                 direction,
1041                 channelInfo->streamPosition,
1042                 channelInfo->streamLocation,
1043                 Streaming::AmdtpPortInfo::E_Midi
1044         );
1045
1046         break;
1047     default:
1048     // unsupported
1049         break;
1050     }
1051
1052     if (!p) {
1053         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->name.c_str());
1054     }
1055
1056     return true;
1057 }
1058
1059 bool
1060 Device::lock() {
1061     fb_octlet_t result;
1062
1063     debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device at node %d\n", getNodeId());
1064
1065     bool snoopMode = false;
1066     if(!getOption("snoopMode", snoopMode)) {
1067         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1068     }
1069
1070     if (snoopMode) {
1071         debugWarning("Lock not supported in snoop mode\n");
1072         return true; //FIXME: this should be false
1073     } else {
1074
1075     // get a notifier to handle device notifications
1076         nodeaddr_t notify_address;
1077         notify_address = get1394Service().findFreeARMBlock(
1078                             DICE_NOTIFIER_BASE_ADDRESS,
1079                             DICE_NOTIFIER_BLOCK_LENGTH,
1080                             DICE_NOTIFIER_BLOCK_LENGTH);
1081    
1082         if (notify_address == 0xFFFFFFFFFFFFFFFFLLU) {
1083             debugError("Could not find free ARM block for notification\n");
1084             return false;
1085         }
1086    
1087         m_notifier = new Device::Notifier(*this, notify_address);
1088    
1089         if(!m_notifier) {
1090             debugError("Could not allocate notifier\n");
1091             return false;
1092         }
1093    
1094         if (!get1394Service().registerARMHandler(m_notifier)) {
1095             debugError("Could not register notifier\n");
1096             delete m_notifier;
1097             m_notifier=NULL;
1098             return false;
1099         }
1100    
1101         // register this notifier
1102         fb_nodeaddr_t addr = DICE_REGISTER_BASE
1103                         + m_global_reg_offset
1104                         + DICE_REGISTER_GLOBAL_OWNER;
1105    
1106         // registry offsets should always be smaller than 0x7FFFFFFF
1107         // because otherwise base + offset > 64bit
1108         if(m_global_reg_offset & 0x80000000) {
1109             debugError("register offset not initialized yet\n");
1110             return false;
1111         }
1112    
1113         fb_nodeaddr_t swap_value = ((0xFFC0) | get1394Service().getLocalNodeId());
1114         swap_value = swap_value << 48;
1115         swap_value |= m_notifier->getStart();
1116    
1117         if (!get1394Service().lockCompareSwap64(getNodeId() | 0xFFC0,
1118                                                 addr, DICE_OWNER_NO_OWNER,
1119                                                 swap_value, &result )) {
1120             debugWarning("Could not register ourselves as device owner\n");
1121             return false;
1122         }
1123    
1124         if (result != DICE_OWNER_NO_OWNER && result != swap_value) {
1125             debugWarning("Could not register ourselves as device owner, unexpected register value: 0x%016"PRIX64"\n", result);
1126             return false;
1127         }
1128    
1129         return true;
1130     }
1131 }
1132
1133
1134 bool
1135 Device::unlock() {
1136     fb_octlet_t result;
1137
1138     bool snoopMode = false;
1139     if(!getOption("snoopMode", snoopMode)) {
1140         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1141     }
1142
1143     if (snoopMode) {
1144         debugWarning("Unlock not supported in snoop mode\n");
1145         return true; //FIXME: this should be false
1146     } else {
1147         if(!m_notifier) {
1148             debugWarning("Request to unlock, but no notifier present!\n");
1149             return false;
1150         }
1151    
1152         fb_nodeaddr_t addr = DICE_REGISTER_BASE
1153                         + m_global_reg_offset
1154                         + DICE_REGISTER_GLOBAL_OWNER;
1155    
1156         // registry offsets should always be smaller than 0x7FFFFFFF
1157         // because otherwise base + offset > 64bit
1158         if(m_global_reg_offset & 0x80000000) {
1159             debugError("register offset not initialized yet\n");
1160             return false;
1161         }
1162    
1163         fb_nodeaddr_t compare_value = ((0xFFC0) | get1394Service().getLocalNodeId());
1164         compare_value <<= 48;
1165         compare_value |= m_notifier->getStart();
1166    
1167         if (!get1394Service().lockCompareSwap64(  getNodeId() | 0xFFC0, addr, compare_value,
1168                                         DICE_OWNER_NO_OWNER, &result )) {
1169             debugWarning("Could not unregister ourselves as device owner\n");
1170             return false;
1171         }
1172    
1173         get1394Service().unregisterARMHandler(m_notifier);
1174         delete m_notifier;
1175         m_notifier=NULL;
1176    
1177         return true;
1178     }
1179 }
1180
1181 bool
1182 Device::enableStreaming() {
1183     bool snoopMode = false;
1184     if(!getOption("snoopMode", snoopMode)) {
1185         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1186     }
1187
1188     if (snoopMode) {
1189         debugWarning("Stream should be already running for snoop mode\n");
1190         return true;
1191     } else {
1192         return enableIsoStreaming();
1193     }
1194 }
1195
1196 bool
1197 Device::disableStreaming() {
1198     bool snoopMode = false;
1199     if(!getOption("snoopMode", snoopMode)) {
1200         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1201     }
1202
1203     if (snoopMode) {
1204         debugWarning("Won't disable stream in snoop mode\n");
1205         return true;
1206     } else {
1207         return disableIsoStreaming();
1208     }
1209 }
1210
1211 int
1212 Device::getStreamCount() {
1213     return m_receiveProcessors.size() + m_transmitProcessors.size();
1214 }
1215
1216 Streaming::StreamProcessor *
1217 Device::getStreamProcessorByIndex(int i) {
1218
1219     if (i<(int)m_receiveProcessors.size()) {
1220         return m_receiveProcessors.at(i);
1221     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1222         return m_transmitProcessors.at(i-m_receiveProcessors.size());
1223     }
1224
1225     return NULL;
1226 }
1227
1228 enum FFADODevice::eStreamingState
1229 Device::getStreamingState()
1230 {
1231     if (isIsoStreamingEnabled() == 0)
1232         return eSS_Idle;
1233     // If streaming is not idle assume both transmit and receive are
1234     // active since there is currently no way to distinguish these.
1235     return eSS_Both;
1236 }
1237
1238 bool
1239 Device::startstopStreamByIndex(int i, const bool start) {
1240     bool snoopMode = false;
1241     fb_nodeaddr_t base_address;   // holds DICE_REGISTER_TX_ISOC_BASE or DICE_REGISTER_RX_ISOC_BASE
1242     int n;                       // number of streaming processor
1243
1244     Streaming::StreamProcessor *p;
1245
1246     if(!getOption("snoopMode", snoopMode)) {
1247         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1248     }
1249
1250 #if USE_OLD_DEFENSIVE_STREAMING_PROTECTION
1251     if (!snoopMode && isIsoStreamingEnabled()) {
1252         debugError("Cannot start streams while streaming is enabled\n");
1253         return false;
1254     }
1255 #endif
1256
1257     if (i<(int)m_receiveProcessors.size()) {
1258         n=i;
1259         p = m_receiveProcessors.at(n);
1260         base_address = DICE_REGISTER_TX_ISOC_BASE;
1261         setRXTXfuncs (Streaming::Port::E_Capture);
1262     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1263         n=i-m_receiveProcessors.size();
1264         p=m_transmitProcessors.at(n);
1265         base_address = DICE_REGISTER_RX_ISOC_BASE;
1266         setRXTXfuncs (Streaming::Port::E_Playback);
1267     } else {
1268         debugError("SP index %d out of range!\n",i);
1269         return false;
1270     }
1271
1272     if (start == true) {
1273         if(snoopMode) { // a stream from the device to another host
1274             fb_quadlet_t reg_isoch;
1275             // check value of ISO_CHANNEL register
1276             if(!(*this.*readFunc)(n, base_address, &reg_isoch)) {
1277                 debugError("Could not read ISO_CHANNEL register for A%s %d\n", dir, n);
1278                 p->setChannel(-1);
1279                 return false;
1280             }
1281             int isochannel = reg_isoch;
1282             debugOutput(DEBUG_LEVEL_VERBOSE,
1283                     "(%p) Snooping %s from channel %d\n",
1284                     this, dir, isochannel);
1285             p->setChannel(isochannel);
1286         } else {
1287             // allocate ISO channel
1288             int isochannel = allocateIsoChannel(p->getMaxPacketSize());
1289             if(isochannel<0) {
1290                 debugError("Could not allocate iso channel for SP %d (A%s %d)\n", i, dir, n);
1291                 return false;
1292             }
1293             debugOutput(DEBUG_LEVEL_VERBOSE,
1294                     "(%p) Allocated channel %u for %s\n",
1295                     this, isochannel, dir);
1296             p->setChannel(isochannel);
1297
1298             fb_quadlet_t reg_isoch;
1299             // check value of ISO_CHANNEL register
1300             if(!(*this.*readFunc)(n, base_address, &reg_isoch)) {
1301                 debugError("Could not read ISO_CHANNEL register for A%s %d\n", dir, n);
1302                 p->setChannel(-1);
1303                 deallocateIsoChannel(isochannel);
1304                 return false;
1305             }
1306             if(reg_isoch != 0xFFFFFFFFUL) {
1307                 debugWarning("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08"PRIX32") for A%s %d\n", reg_isoch, dir, n);
1308                 /* The ISO channel has already been registered, probably
1309                  * because the device was running before and jackd just
1310                  * crashed. Let's simply reuse the previously selected
1311                  * ISO channel.
1312                  *
1313                  * FIXME: try to reset the channel register and
1314                  * return to a clean state
1315                  */
1316                 deallocateIsoChannel(isochannel);
1317                 p->setChannel(reg_isoch);
1318 #if 0
1319                 /* FIXME: Looks like it's not necessary to ask the IRM.
1320                  * Just use the already registered ISO channel.
1321                  */
1322                 // ask the IRM to use this channel
1323                 if (get1394Service().allocateFixedIsoChannelGeneric(reg_isoch,p->getMaxPacketSize()) < 0) {
1324                     debugError("Cannot allocate iso channel (0x%08"PRIX32") for ATX %d\n", reg_isoch, n);
1325                 }
1326 #endif
1327                 isochannel=reg_isoch;
1328             }
1329
1330             // write value of ISO_CHANNEL register
1331             reg_isoch = isochannel;
1332             if(!(*this.*writeFunc)(n, base_address, reg_isoch)) {
1333                 debugError("Could not write ISO_CHANNEL register for A%s %d\n", dir, n);
1334                 p->setChannel(-1);
1335                 deallocateIsoChannel(isochannel);
1336                 return false;
1337             }
1338         }
1339         return true;
1340     } else {
1341         // stop
1342         if(!snoopMode) {
1343             unsigned int isochannel = p->getChannel();
1344
1345             fb_quadlet_t reg_isoch;
1346             // check value of ISO_CHANNEL register
1347             if(!(*this.*readFunc)(n, base_address, &reg_isoch)) {
1348                 debugError("Could not read ISO_CHANNEL register for A%s %d\n", dir, n);
1349                 return false;
1350             }
1351             if(reg_isoch != isochannel) {
1352                 debugError("ISO_CHANNEL register != 0x%08"PRIX32" (=0x%08"PRIX32") for A%s %d\n", isochannel, reg_isoch, dir, n);
1353                 return false;
1354             }
1355
1356             // write value of ISO_CHANNEL register
1357             reg_isoch=0xFFFFFFFFUL;
1358             if(!writeTxReg(n, base_address, reg_isoch)) {
1359                 debugError("Could not write ISO_CHANNEL register for A%s %d\n", dir, n);
1360                 return false;
1361             }
1362
1363             // deallocate ISO channel
1364             if(!deallocateIsoChannel(isochannel)) {
1365                 debugError("Could not deallocate iso channel for SP %d (A%s %d)\n",i, dir, n);
1366                 return false;
1367             }
1368         }
1369         p->setChannel(-1);
1370         return true;
1371     }
1372 }
1373
1374 bool
1375 Device::startStreamByIndex(int i) {
1376     return startstopStreamByIndex(i, true); // start stream
1377 }
1378
1379 bool
1380 Device::stopStreamByIndex(int i) {
1381     return startstopStreamByIndex(i, false); // stop stream
1382 }
1383
1384 // helper routines
1385
1386 // allocate ISO resources for the SP's
1387 int Device::allocateIsoChannel(unsigned int packet_size) {
1388     unsigned int bandwidth=8+packet_size;
1389
1390     int ch=get1394Service().allocateIsoChannelGeneric(bandwidth);
1391
1392     debugOutput(DEBUG_LEVEL_VERBOSE, "allocated channel %d, bandwidth %d\n",
1393         ch, bandwidth);
1394
1395     return ch;
1396 }
1397 // deallocate ISO resources
1398 bool Device::deallocateIsoChannel(int channel) {
1399     debugOutput(DEBUG_LEVEL_VERBOSE, "freeing channel %d\n",channel);
1400     return get1394Service().freeIsoChannel(channel);
1401 }
1402
1403 bool
1404 Device::enableIsoStreaming() {
1405     return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_ENABLE);
1406 }
1407
1408 bool
1409 Device::disableIsoStreaming() {
1410     return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_DISABLE);
1411 }
1412
1413 bool
1414 Device::isIsoStreamingEnabled() {
1415     fb_quadlet_t result;
1416     readGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, &result);
1417     // I don't know what exactly is 'enable',
1418     // but disable is definately == 0
1419     return (result != DICE_ISOSTREAMING_DISABLE);
1420 }
1421
1422 /**
1423  * @brief performs a masked bit register equals 0 check on the global parameter space
1424  * @return true if readGlobalReg(offset) & mask == 0
1425  */
1426 bool
1427 Device::maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) {
1428     fb_quadlet_t result;
1429     readGlobalReg(offset, &result);
1430     return ((result & mask) == 0);
1431 }
1432 /**
1433  * @brief performs a masked bit register not equal to 0 check on the global parameter space
1434  * @return true if readGlobalReg(offset) & mask != 0
1435  */
1436 bool
1437 Device::maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) {
1438     return !maskedCheckZeroGlobalReg(offset, mask);
1439 }
1440
1441 stringlist
1442 Device::getTxNameString(unsigned int i) {
1443     stringlist names;
1444     char namestring[DICE_TX_NAMES_SIZE+1];
1445
1446     if (!readTxRegBlock(i, DICE_REGISTER_TX_NAMES_BASE,
1447                         (fb_quadlet_t *)namestring, DICE_TX_NAMES_SIZE)) {
1448         debugError("Could not read TX name string \n");
1449         return names;
1450     }
1451
1452     // Strings from the device are always little-endian,
1453     // so byteswap for big-endian machines
1454     #if __BYTE_ORDER == __BIG_ENDIAN
1455     byteSwapBlock((quadlet_t *)namestring, DICE_TX_NAMES_SIZE/4);
1456     #endif
1457     namestring[DICE_TX_NAMES_SIZE]='\0';
1458     return splitNameString(std::string(namestring));
1459 }
1460
1461 stringlist
1462 Device::getRxNameString(unsigned int i) {
1463     stringlist names;
1464     char namestring[DICE_RX_NAMES_SIZE+1];
1465
1466     if (!readRxRegBlock(i, DICE_REGISTER_RX_NAMES_BASE,
1467                         (fb_quadlet_t *)namestring, DICE_RX_NAMES_SIZE)) {
1468         debugError("Could not read RX name string \n");
1469         return names;
1470     }
1471
1472     // Strings from the device are always little-endian,
1473     // so byteswap for big-endian machines
1474     #if __BYTE_ORDER == __BIG_ENDIAN
1475     byteSwapBlock((quadlet_t *)namestring, DICE_RX_NAMES_SIZE/4);
1476     #endif
1477     namestring[DICE_RX_NAMES_SIZE]='\0';
1478     return splitNameString(std::string(namestring));
1479 }
1480
1481 stringlist
1482 Device::getCptrNameString(unsigned int i) {
1483     if (m_eap) return m_eap->getCptrNameString(i);
1484     else return getTxNameString(i);
1485 }
1486
1487 stringlist
1488 Device::getPbckNameString(unsigned int i) {
1489     if (m_eap) return m_eap->getPbckNameString(i);
1490     return getRxNameString(i);
1491 }
1492
1493 stringlist
1494 Device::getClockSourceNameString() {
1495     stringlist names;
1496     char namestring[DICE_CLOCKSOURCENAMES_SIZE+1];
1497
1498     if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_CLOCKSOURCENAMES,
1499                       (fb_quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE)) {
1500         debugError("Could not read CLOCKSOURCE name string \n");
1501         return names;
1502     }
1503
1504     // Strings from the device are always little-endian,
1505     // so byteswap for big-endian machines
1506     #if __BYTE_ORDER == __BIG_ENDIAN
1507     byteSwapBlock((quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE/4);
1508     #endif
1509     namestring[DICE_CLOCKSOURCENAMES_SIZE]='\0';
1510     return splitNameString(std::string(namestring));
1511 }
1512
1513
1514 stringlist
1515 Device::splitNameString(std::string in) {
1516     in = in.substr(0,in.find("\\\\"));
1517     return stringlist::splitString(in, "\\");
1518 }
1519
1520
1521 // I/O routines
1522 bool
1523 Device::initIoFunctions() {
1524
1525     // offsets and sizes are returned in quadlets, but we use byte values
1526     if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_OFF, &m_global_reg_offset)) {
1527         debugError("Could not initialize m_global_reg_offset\n");
1528         return false;
1529     }
1530     m_global_reg_offset*=4;
1531
1532     if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_SZ, &m_global_reg_size)) {
1533         debugError("Could not initialize m_global_reg_size\n");
1534         return false;
1535     }
1536     m_global_reg_size*=4;
1537
1538     if(!readReg(DICE_REGISTER_TX_PAR_SPACE_OFF, &m_tx_reg_offset)) {
1539         debugError("Could not initialize m_tx_reg_offset\n");
1540         return false;
1541     }
1542     m_tx_reg_offset*=4;
1543
1544     if(!readReg(DICE_REGISTER_TX_PAR_SPACE_SZ, &m_tx_reg_size)) {
1545         debugError("Could not initialize m_tx_reg_size\n");
1546         return false;
1547     }
1548     m_tx_reg_size*=4;
1549
1550     if(!readReg(DICE_REGISTER_RX_PAR_SPACE_OFF, &m_rx_reg_offset)) {
1551         debugError("Could not initialize m_rx_reg_offset\n");
1552         return false;
1553     }
1554     m_rx_reg_offset*=4;
1555
1556     if(!readReg(DICE_REGISTER_RX_PAR_SPACE_SZ, &m_rx_reg_size)) {
1557         debugError("Could not initialize m_rx_reg_size\n");
1558         return false;
1559     }
1560     m_rx_reg_size*=4;
1561
1562     if(!readReg(DICE_REGISTER_UNUSED1_SPACE_OFF, &m_unused1_reg_offset)) {
1563         debugError("Could not initialize m_unused1_reg_offset\n");
1564         return false;
1565     }
1566     m_unused1_reg_offset*=4;
1567
1568     if(!readReg(DICE_REGISTER_UNUSED1_SPACE_SZ, &m_unused1_reg_size)) {
1569         debugError("Could not initialize m_unused1_reg_size\n");
1570         return false;
1571     }
1572     m_unused1_reg_size*=4;
1573
1574     if(!readReg(DICE_REGISTER_UNUSED2_SPACE_OFF, &m_unused2_reg_offset)) {
1575         debugError("Could not initialize m_unused2_reg_offset\n");
1576         return false;
1577     }
1578     m_unused2_reg_offset*=4;
1579
1580     if(!readReg(DICE_REGISTER_UNUSED2_SPACE_SZ, &m_unused2_reg_size)) {
1581         debugError("Could not initialize m_unused2_reg_size\n");
1582         return false;
1583     }
1584     m_unused2_reg_size*=4;
1585
1586     if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_NB_TX, &m_nb_tx)) {
1587         debugError("Could not initialize m_nb_tx\n");
1588         return false;
1589     }
1590     if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_SZ_TX, &m_tx_size)) {
1591         debugError("Could not initialize m_tx_size\n");
1592         return false;
1593     }
1594     m_tx_size*=4;
1595
1596     if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_NB_RX, &m_nb_rx)) {
1597         debugError("Could not initialize m_nb_rx\n");
1598         return false;
1599     }
1600
1601     if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_SZ_RX, &m_rx_size)) {
1602         debugError("Could not initialize m_rx_size\n");
1603         return false;
1604     }
1605     m_rx_size*=4;
1606
1607     // FIXME: verify this and clean it up.
1608     /* special case for Alesis io14, which announces two receive transmitters,
1609      * but only has one. Same is true for Alesis Multimix16.
1610      */
1611     if (FW_VENDORID_ALESIS == getConfigRom().getNodeVendorId()) {
1612         switch (getConfigRom().getModelId()) {
1613             case 0x00000001:
1614             case 0x00000000:
1615                 m_nb_rx = 1;
1616                 break;
1617         }
1618     }
1619
1620 #if USE_OLD_DEFENSIVE_STREAMING_PROTECTION
1621     // FIXME: after a crash, the device might still be streaming. We
1622     // simply force a stop now (unless in snoopMode) to return to a
1623     // clean state.
1624     bool snoopMode = false;
1625     if(!getOption("snoopMode", snoopMode)) {
1626         //debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1627     }
1628
1629     if (!snoopMode) {
1630         disableIsoStreaming();
1631     }
1632 #endif
1633
1634     debugOutput(DEBUG_LEVEL_VERBOSE,"DICE Parameter Space info:\n");
1635     debugOutput(DEBUG_LEVEL_VERBOSE," Global  : offset=%04X size=%04d\n", m_global_reg_offset, m_global_reg_size);
1636     debugOutput(DEBUG_LEVEL_VERBOSE," TX      : offset=%04X size=%04d\n", m_tx_reg_offset, m_tx_reg_size);
1637     debugOutput(DEBUG_LEVEL_VERBOSE,"               nb=%4d size=%04d\n", m_nb_tx, m_tx_size);
1638     debugOutput(DEBUG_LEVEL_VERBOSE," RX      : offset=%04X size=%04d\n", m_rx_reg_offset, m_rx_reg_size);
1639     debugOutput(DEBUG_LEVEL_VERBOSE,"               nb=%4d size=%04d\n", m_nb_rx, m_rx_size);
1640     debugOutput(DEBUG_LEVEL_VERBOSE," UNUSED1 : offset=%04X size=%04d\n", m_unused1_reg_offset, m_unused1_reg_size);
1641     debugOutput(DEBUG_LEVEL_VERBOSE," UNUSED2 : offset=%04X size=%04d\n", m_unused2_reg_offset, m_unused2_reg_size);
1642
1643     return true;
1644 }
1645
1646 bool
1647 Device::readReg(fb_nodeaddr_t offset, fb_quadlet_t *result) {
1648     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading base register offset 0x%08"PRIX64"\n", offset);
1649
1650     if(offset >= DICE_INVALID_OFFSET) {
1651         debugError("invalid offset: 0x%016"PRIX64"\n", offset);
1652         return false;
1653     }
1654
1655     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1656     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1657
1658     if(!get1394Service().read_quadlet( nodeId, addr, result ) ) {
1659         debugError("Could not read from node 0x%04X addr 0x%12"PRIX64"\n", nodeId, addr);
1660         return false;
1661     }
1662
1663     *result = CondSwapFromBus32(*result);
1664
1665     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Read result: 0x%08"PRIX32"\n", *result);
1666
1667     return true;
1668 }
1669
1670 bool
1671 Device::writeReg(fb_nodeaddr_t offset, fb_quadlet_t data) {
1672     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08"PRIX64", data: 0x%08"PRIX32"\n",
1673         offset, data);
1674
1675     if(offset >= DICE_INVALID_OFFSET) {
1676         debugError("invalid offset: 0x%012"PRIX64"\n", offset);
1677         return false;
1678     }
1679
1680     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1681     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1682
1683     if(!get1394Service().write_quadlet( nodeId, addr, CondSwapToBus32(data) ) ) {
1684         debugError("Could not write to node 0x%04X addr 0x%12"PRIX64"\n", nodeId, addr);
1685         return false;
1686     }
1687     return true;
1688 }
1689
1690 bool
1691 Device::readRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1692     debugOutput(DEBUG_LEVEL_VERBOSE,
1693                 "Reading base register offset 0x%08"PRIX64", length %zd, to %p\n",
1694                 offset, length, data);
1695     const int blocksize_quads = 512/4;
1696
1697     if(offset >= DICE_INVALID_OFFSET) {
1698         debugError("invalid offset: 0x%012"PRIX64"\n", offset);
1699         return false;
1700     }
1701
1702     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1703     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1704     int quads_done = 0;
1705     // round to next full quadlet
1706     int length_quads = (length+3)/4;
1707     while(quads_done < length_quads) {
1708         fb_nodeaddr_t curr_addr = addr + quads_done*4;
1709         fb_quadlet_t *curr_data = data + quads_done;
1710         int quads_todo = length_quads - quads_done;
1711         debugOutput(DEBUG_LEVEL_VERBOSE, "reading addr: 0x%012"PRIX64", %d quads to %p\n", curr_addr, quads_todo, curr_data);
1712        
1713         if (quads_todo > blocksize_quads) {
1714             debugOutput(DEBUG_LEVEL_VERBOSE, "Truncating read from %d to %d quadlets\n", quads_todo, blocksize_quads);
1715             quads_todo = blocksize_quads;
1716         }
1717         #ifdef DEBUG
1718         if (quads_todo < 0) {
1719             debugError("BUG: quads_todo < 0: %d\n", quads_todo);
1720         }
1721         #endif
1722
1723         if(!get1394Service().read( nodeId, curr_addr, quads_todo, curr_data ) ) {
1724             debugError("Could not read %d quadlets from node 0x%04X addr 0x%012"PRIX64"\n", quads_todo, nodeId, curr_addr);
1725             return false;
1726         }
1727         quads_done += quads_todo;
1728     }
1729
1730     byteSwapFromBus(data, length/4);
1731     return true;
1732 }
1733
1734 bool
1735 Device::writeRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1736     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08"PRIX64", length: %zd\n",
1737         offset, length);
1738     const int blocksize_quads = 512/4;
1739
1740     if(offset >= DICE_INVALID_OFFSET) {
1741         debugError("invalid offset: 0x%012"PRIX64"\n", offset);
1742         return false;
1743     }
1744
1745     fb_quadlet_t data_out[length/4];
1746     memcpy(data_out, data, length);
1747     byteSwapToBus(data_out, length/4);
1748
1749     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1750     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1751     int quads_done = 0;
1752     int length_quads = (length+3)/4;
1753     while(quads_done < length_quads) {
1754         fb_nodeaddr_t curr_addr = addr + quads_done*4;
1755         fb_quadlet_t *curr_data = data_out + quads_done;
1756         int quads_todo = length_quads - quads_done;
1757         if (quads_todo > blocksize_quads) {
1758             debugOutput(DEBUG_LEVEL_VERBOSE, "Truncating write from %d to %d quadlets\n", quads_todo, blocksize_quads);
1759             quads_todo = blocksize_quads;
1760         }
1761         #ifdef DEBUG
1762         if (quads_todo < 0) {
1763             debugError("BUG: quads_todo < 0: %d\n", quads_todo);
1764         }
1765         #endif
1766
1767         if(!get1394Service().write( nodeId, addr, quads_todo, curr_data ) ) {
1768             debugError("Could not write %d quadlets to node 0x%04X addr 0x%012"PRIX64"\n", quads_todo, nodeId, curr_addr);
1769             return false;
1770         }
1771         quads_done += quads_todo;
1772     }
1773
1774     return true;
1775 }
1776
1777 bool
1778 Device::readGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t *result) {
1779     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register offset 0x%04"PRIX64"\n", offset);
1780
1781     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, sizeof(fb_quadlet_t));
1782     return readReg(m_global_reg_offset + offset_gl, result);
1783 }
1784
1785 bool
1786 Device::writeGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t data) {
1787     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register offset 0x%08"PRIX64", data: 0x%08"PRIX32"\n",
1788         offset, data);
1789
1790     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, sizeof(fb_quadlet_t));
1791     return writeReg(m_global_reg_offset + offset_gl, data);
1792 }
1793
1794 bool
1795 Device::readGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1796     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register block offset 0x%04"PRIX64", length %zd bytes\n",
1797         offset, length);
1798
1799     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, length);
1800     return readRegBlock(m_global_reg_offset + offset_gl, data, length);
1801 }
1802
1803 bool
1804 Device::writeGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1805     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register block offset 0x%04"PRIX64", length: %zd bytes\n",
1806         offset, length);
1807
1808     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, length);
1809     return writeRegBlock(m_global_reg_offset + offset_gl, data, length);
1810 }
1811
1812 fb_nodeaddr_t
1813 Device::globalOffsetGen(fb_nodeaddr_t offset, size_t length) {
1814
1815     // registry offsets should always be smaller than 0x7FFFFFFF
1816     // because otherwise base + offset > 64bit
1817     if(m_global_reg_offset & 0x80000000) {
1818         debugError("register offset not initialized yet\n");
1819         return DICE_INVALID_OFFSET;
1820     }
1821     // out-of-range check
1822     if(offset+length > m_global_reg_offset+m_global_reg_size) {
1823         debugError("register offset+length too large: 0x%04"PRIX64"\n", offset + length);
1824         return DICE_INVALID_OFFSET;
1825     }
1826
1827     return offset;
1828 }
1829
1830 bool
1831 Device::readTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) {
1832     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Reading tx %d register offset 0x%04"PRIX64"\n", i, offset);
1833
1834     fb_nodeaddr_t offset_tx = txOffsetGen(i, offset, sizeof(fb_quadlet_t));
1835     return readReg(m_tx_reg_offset + offset_tx, result);
1836 }
1837
1838 bool
1839 Device::writeTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) {
1840     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing tx %d register offset 0x%08"PRIX64", data: 0x%08"PRIX32"\n",
1841         i, offset, data);
1842
1843     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, sizeof(fb_quadlet_t));
1844     return writeReg(m_tx_reg_offset + offset_tx, data);
1845 }
1846
1847 bool
1848 Device::readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1849     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04"PRIX64", length: %zd bytes\n",
1850         offset, length);
1851
1852     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length);
1853     return readRegBlock(m_tx_reg_offset + offset_tx, data, length);
1854 }
1855
1856 bool
1857 Device::writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1858     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04"PRIX64", length: %zd bytes\n",
1859         offset, length);
1860
1861     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length);
1862     return writeRegBlock(m_tx_reg_offset + offset_tx, data, length);
1863 }
1864
1865 fb_nodeaddr_t
1866 Device::txOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) {
1867     // registry offsets should always be smaller than 0x7FFFFFFF
1868     // because otherwise base + offset > 64bit
1869     if(m_tx_reg_offset & 0x80000000) {
1870         debugError("register offset not initialized yet\n");
1871         return DICE_INVALID_OFFSET;
1872     }
1873     if(m_nb_tx & 0x80000000) {
1874         debugError("m_nb_tx not initialized yet\n");
1875         return DICE_INVALID_OFFSET;
1876     }
1877     if(m_tx_size & 0x80000000) {
1878         debugError("m_tx_size not initialized yet\n");
1879         return DICE_INVALID_OFFSET;
1880     }
1881     if(i >= m_nb_tx) {
1882         debugError("TX index out of range\n");
1883         return DICE_INVALID_OFFSET;
1884     }
1885
1886     fb_nodeaddr_t offset_tx = DICE_REGISTER_TX_PARAM(m_tx_size, i, offset);
1887
1888     // out-of-range check
1889     if(offset_tx + length > m_tx_reg_offset+4+m_tx_reg_size*m_nb_tx) {
1890         debugError("register offset+length too large: 0x%04"PRIX64"\n", offset_tx + length);
1891         return DICE_INVALID_OFFSET;
1892     }
1893
1894     return offset_tx;
1895 }
1896
1897 bool
1898 Device::readRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) {
1899     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx %d register offset 0x%04"PRIX64"\n", i, offset);
1900
1901     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t));
1902     return readReg(m_rx_reg_offset + offset_rx, result);
1903 }
1904
1905 bool
1906 Device::writeRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) {
1907     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register offset 0x%08"PRIX64", data: 0x%08"PRIX32"\n",
1908         offset, data);
1909
1910     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t));
1911     return writeReg(m_rx_reg_offset + offset_rx, data);
1912 }
1913
1914 bool
1915 Device::readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1916     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04"PRIX64", length: %zd bytes\n",
1917         offset, length);
1918
1919     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length);
1920     return readRegBlock(m_rx_reg_offset + offset_rx, data, length);
1921 }
1922
1923 bool
1924 Device::writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1925     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04"PRIX64", length: %zd bytes\n",
1926         offset, length);
1927
1928     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length);
1929     return writeRegBlock(m_rx_reg_offset + offset_rx, data, length);
1930 }
1931
1932 fb_nodeaddr_t
1933 Device::rxOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) {
1934     // registry offsets should always be smaller than 0x7FFFFFFF
1935     // because otherwise base + offset > 64bit
1936     if(m_rx_reg_offset & 0x80000000) {
1937         debugError("register offset not initialized yet\n");
1938         return DICE_INVALID_OFFSET;
1939     }
1940     if(m_nb_rx & 0x80000000) {
1941         debugError("m_nb_rx not initialized yet\n");
1942         return DICE_INVALID_OFFSET;
1943     }
1944     if(m_rx_size & 0x80000000) {
1945         debugError("m_rx_size not initialized yet\n");
1946         return DICE_INVALID_OFFSET;
1947     }
1948     if(i >= m_nb_rx) {
1949         debugError("RX index out of range\n");
1950         return DICE_INVALID_OFFSET;
1951     }
1952
1953     fb_nodeaddr_t offset_rx = DICE_REGISTER_RX_PARAM(m_rx_size, i, offset);
1954
1955     // out-of-range check
1956     if(offset_rx + length > m_rx_reg_offset+4+m_rx_reg_size*m_nb_rx) {
1957         debugError("register offset+length too large: 0x%04"PRIX64"\n", offset_rx + length);
1958         return DICE_INVALID_OFFSET;
1959     }
1960     return offset_rx;
1961 }
1962
1963
1964 // the notifier
1965
1966 Device::Notifier::Notifier(Device &d, nodeaddr_t start)
1967  : ARMHandler(d.get1394Service(), start, DICE_NOTIFIER_BLOCK_LENGTH,
1968               RAW1394_ARM_READ | RAW1394_ARM_WRITE | RAW1394_ARM_LOCK,
1969               RAW1394_ARM_WRITE, 0)
1970  , m_device(d)
1971 {
1972     // switch over the debug module to that of this device instead of the 1394 service
1973     m_debugModule = d.m_debugModule;
1974 }
1975
1976 Device::Notifier::~Notifier()
1977 {
1978
1979 }
1980
1981 }
Note: See TracBrowser for help on using the browser.