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

Revision 2048, 66.5 kB (checked in by adi, 12 years ago)

DICE: Initiliaze I/O functions and EAP

Patch by Philippe Carriere

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