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

Revision 2201, 68.3 kB (checked in by jwoithe, 12 years ago)

DICE: an attempt to further refine the patch from r2200 based on the direction of the ports being constructed. Compile-tested only.

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