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

Revision 1543, 70.5 kB (checked in by ppalmers, 14 years ago)

- Clean up class names
- Change probe code for all devices (except MOTU) to use the config file based approach

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