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

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