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

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

- Implement basic HSS1394 support for the Stanton SCS devices
- Start of the implementation of a generic TCAT DICE EAP control
- Reworked part of the busreset / ARM handler code

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     readGlobalRegBlock(DICE_REGISTER_GLOBAL_VERSION, reinterpret_cast<fb_quadlet_t *>(&tmp_quadlet), sizeof(fb_quadlet_t));
574     debugOutput(DEBUG_LEVEL_NORMAL,"  Version          : 0x%08X\n", tmp_quadlet);
575    
576     readGlobalReg(DICE_REGISTER_GLOBAL_VERSION, &tmp_quadlet);
577     debugOutput(DEBUG_LEVEL_NORMAL,"  Version          : 0x%08X (%u.%u.%u.%u)\n",
578         tmp_quadlet,
579         DICE_DRIVER_SPEC_VERSION_NUMBER_GET_A(tmp_quadlet),
580         DICE_DRIVER_SPEC_VERSION_NUMBER_GET_B(tmp_quadlet),
581         DICE_DRIVER_SPEC_VERSION_NUMBER_GET_C(tmp_quadlet),
582         DICE_DRIVER_SPEC_VERSION_NUMBER_GET_D(tmp_quadlet)
583         );
584
585     readGlobalReg(DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, &tmp_quadlet);
586     debugOutput(DEBUG_LEVEL_VERBOSE,"  Clock caps       : 0x%08X\n",tmp_quadlet);
587
588     diceNameVector names=getClockSourceNameString();
589     debugOutput(DEBUG_LEVEL_VERBOSE,"  Clock sources    :\n");
590
591     for ( diceNameVectorIterator it = names.begin();
592           it != names.end();
593           ++it )
594     {
595         debugOutput(DEBUG_LEVEL_VERBOSE,"    %s\n", (*it).c_str());
596     }
597
598     debugOutput(DEBUG_LEVEL_VERBOSE," TX param space:\n");
599     debugOutput(DEBUG_LEVEL_VERBOSE,"  Nb of xmit        : %1d\n", m_nb_tx);
600     for (unsigned int i=0;i<m_nb_tx;i++) {
601         debugOutput(DEBUG_LEVEL_VERBOSE,"  Transmitter %d:\n",i);
602
603         readTxReg(i, DICE_REGISTER_TX_ISOC_BASE, &tmp_quadlet);
604         debugOutput(DEBUG_LEVEL_VERBOSE,"   ISO channel       : %3d\n", tmp_quadlet);
605         readTxReg(i, DICE_REGISTER_TX_SPEED_BASE, &tmp_quadlet);
606         debugOutput(DEBUG_LEVEL_VERBOSE,"   ISO speed         : %3d\n", tmp_quadlet);
607
608         readTxReg(i, DICE_REGISTER_TX_NB_AUDIO_BASE, &tmp_quadlet);
609         debugOutput(DEBUG_LEVEL_VERBOSE,"   Nb audio channels : %3d\n", tmp_quadlet);
610         readTxReg(i, DICE_REGISTER_TX_MIDI_BASE, &tmp_quadlet);
611         debugOutput(DEBUG_LEVEL_VERBOSE,"   Nb midi channels  : %3d\n", tmp_quadlet);
612
613         readTxReg(i, DICE_REGISTER_TX_AC3_CAPABILITIES_BASE, &tmp_quadlet);
614         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 caps          : 0x%08X\n", tmp_quadlet);
615         readTxReg(i, DICE_REGISTER_TX_AC3_ENABLE_BASE, &tmp_quadlet);
616         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 enable        : 0x%08X\n", tmp_quadlet);
617
618         diceNameVector channel_names=getTxNameString(i);
619         debugOutput(DEBUG_LEVEL_VERBOSE,"   Channel names     :\n");
620         for ( diceNameVectorIterator it = channel_names.begin();
621             it != channel_names.end();
622             ++it )
623         {
624             debugOutput(DEBUG_LEVEL_VERBOSE,"     %s\n", (*it).c_str());
625         }
626     }
627
628     debugOutput(DEBUG_LEVEL_VERBOSE," RX param space:\n");
629     debugOutput(DEBUG_LEVEL_VERBOSE,"  Nb of recv        : %1d\n", m_nb_tx);
630     for (unsigned int i=0;i<m_nb_rx;i++) {
631         debugOutput(DEBUG_LEVEL_VERBOSE,"  Receiver %d:\n",i);
632
633         readTxReg(i, DICE_REGISTER_RX_ISOC_BASE, &tmp_quadlet);
634         debugOutput(DEBUG_LEVEL_VERBOSE,"   ISO channel       : %3d\n", tmp_quadlet);
635         readTxReg(i, DICE_REGISTER_RX_SEQ_START_BASE, &tmp_quadlet);
636         debugOutput(DEBUG_LEVEL_VERBOSE,"   Sequence start    : %3d\n", tmp_quadlet);
637
638         readTxReg(i, DICE_REGISTER_RX_NB_AUDIO_BASE, &tmp_quadlet);
639         debugOutput(DEBUG_LEVEL_VERBOSE,"   Nb audio channels : %3d\n", tmp_quadlet);
640         readTxReg(i, DICE_REGISTER_RX_MIDI_BASE, &tmp_quadlet);
641         debugOutput(DEBUG_LEVEL_VERBOSE,"   Nb midi channels  : %3d\n", tmp_quadlet);
642
643         readTxReg(i, DICE_REGISTER_RX_AC3_CAPABILITIES_BASE, &tmp_quadlet);
644         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 caps          : 0x%08X\n", tmp_quadlet);
645         readTxReg(i, DICE_REGISTER_RX_AC3_ENABLE_BASE, &tmp_quadlet);
646         debugOutput(DEBUG_LEVEL_VERBOSE,"   AC3 enable        : 0x%08X\n", tmp_quadlet);
647
648         diceNameVector channel_names=getRxNameString(i);
649         debugOutput(DEBUG_LEVEL_VERBOSE,"   Channel names     :\n");
650         for ( diceNameVectorIterator it = channel_names.begin();
651             it != channel_names.end();
652             ++it )
653         {
654             debugOutput(DEBUG_LEVEL_VERBOSE,"     %s\n", (*it).c_str());
655         }
656     }
657     flushDebugOutput();
658 }
659
660 // NOTE on bandwidth calculation
661 // FIXME: The bandwidth allocation calculation can probably be
662 // refined somewhat since this is currently based on a rudimentary
663 // understanding of the iso protocol.
664 // Currently we assume the following.
665 //   * Ack/iso gap = 0.05 us
666 //   * DATA_PREFIX = 0.16 us1
667 //   * DATA_END    = 0.26 us
668 // These numbers are the worst-case figures given in the ieee1394
669 // standard.  This gives approximately 0.5 us of overheads per
670 // packet - around 25 bandwidth allocation units (from the ieee1394
671 // standard 1 bandwidth allocation unit is 125/6144 us).  We further
672 // assume the device is running at S400 (which it should be) so one
673 // allocation unit is equivalent to 1 transmitted byte; thus the
674 // bandwidth allocation required for the packets themselves is just
675 // the size of the packet.
676 bool
677 Device::prepare() {
678     fb_quadlet_t nb_audio;
679     fb_quadlet_t nb_midi;
680     unsigned int nb_channels = 0;
681
682     bool snoopMode = false;
683     if(!getOption("snoopMode", snoopMode)) {
684         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
685     }
686
687     // get the device specific and/or global SP configuration
688     Util::Configuration &config = getDeviceManager().getConfiguration();
689     // base value is the config.h value
690     float recv_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ;
691     float xmit_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ;
692
693     int xmit_max_cycles_early_transmit = AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY;
694     int xmit_transfer_delay = AMDTP_TRANSMIT_TRANSFER_DELAY;
695     int xmit_min_cycles_before_presentation = AMDTP_MIN_CYCLES_BEFORE_PRESENTATION;
696
697     // we can override that globally
698     config.getValueForSetting("streaming.common.recv_sp_dll_bw", recv_sp_dll_bw);
699     config.getValueForSetting("streaming.common.xmit_sp_dll_bw", xmit_sp_dll_bw);
700     config.getValueForSetting("streaming.amdtp.xmit_max_cycles_early_transmit", xmit_max_cycles_early_transmit);
701     config.getValueForSetting("streaming.amdtp.xmit_transfer_delay", xmit_transfer_delay);
702     config.getValueForSetting("streaming.amdtp.xmit_min_cycles_before_presentation", xmit_min_cycles_before_presentation);
703
704     // or override in the device section
705     uint32_t vendorid = getConfigRom().getNodeVendorId();
706     uint32_t modelid = getConfigRom().getModelId();
707     config.getValueForDeviceSetting(vendorid, modelid, "recv_sp_dll_bw", recv_sp_dll_bw);
708     config.getValueForDeviceSetting(vendorid, modelid, "xmit_sp_dll_bw", xmit_sp_dll_bw);
709     config.getValueForDeviceSetting(vendorid, modelid, "xmit_max_cycles_early_transmit", xmit_max_cycles_early_transmit);
710     config.getValueForDeviceSetting(vendorid, modelid, "xmit_transfer_delay", xmit_transfer_delay);
711     config.getValueForDeviceSetting(vendorid, modelid, "xmit_min_cycles_before_presentation", xmit_min_cycles_before_presentation);
712
713     diceNameVector names_audio;
714     diceNameVector names_midi;
715     // prepare receive SP's
716 //     for (unsigned int i=0;i<1;i++) {
717     for (unsigned int i=0; i<m_nb_tx; i++) {
718
719         if(!readTxReg(i, DICE_REGISTER_TX_NB_AUDIO_BASE, &nb_audio)) {
720             debugError("Could not read DICE_REGISTER_TX_NB_AUDIO_BASE register for ATX%u\n",i);
721             continue;
722         }
723         if(!readTxReg(i, DICE_REGISTER_TX_MIDI_BASE, &nb_midi)) {
724             debugError("Could not read DICE_REGISTER_TX_MIDI_BASE register for ATX%u\n",i);
725             continue;
726         }
727
728         // request the channel names
729         names_audio = getTxNameString(i);
730         if (names_audio.size() != nb_audio) {
731             debugWarning("The audio channel name vector is incorrect, using default names\n");
732             names_audio.clear();
733
734             for (unsigned int j=0;j<nb_audio;j++) {
735                 std::ostringstream newname;
736                 newname << "input_" << j;
737                 names_audio.push_back(newname.str());
738             }
739         }
740
741         nb_channels = nb_audio;
742         if(nb_midi) nb_channels += 1; // midi-muxed counts as one
743
744         // construct the MIDI names
745         for (unsigned int j=0;j<nb_midi;j++) {
746             std::ostringstream newname;
747             newname << "midi_in_" << j;
748             names_midi.push_back(newname.str());
749         }
750
751         // construct the streamprocessor
752         Streaming::AmdtpReceiveStreamProcessor *p;
753         p = new Streaming::AmdtpReceiveStreamProcessor(*this,
754                              nb_channels);
755
756         if(!p->init()) {
757             debugFatal("Could not initialize receive processor!\n");
758             delete p;
759             continue;
760         }
761
762         // add audio ports to the processor
763         for (unsigned int j=0;j<nb_audio;j++) {
764             diceChannelInfo channelInfo;
765             channelInfo.name=names_audio.at(j);
766             channelInfo.portType=ePT_Analog;
767             channelInfo.streamPosition=j;
768             channelInfo.streamLocation=0;
769
770             if (!addChannelToProcessor(&channelInfo, p, Streaming::Port::E_Capture)) {
771                 debugError("Could not add channel %s to StreamProcessor\n",
772                     channelInfo.name.c_str());
773                 continue;
774             }
775         }
776
777         // add midi ports to the processor
778         for (unsigned int j=0;j<nb_midi;j++) {
779             diceChannelInfo channelInfo;
780             channelInfo.name=names_midi.at(j);
781             channelInfo.portType=ePT_MIDI;
782             channelInfo.streamPosition=nb_audio;
783             channelInfo.streamLocation=j;
784
785             if (!addChannelToProcessor(&channelInfo, p, Streaming::Port::E_Capture)) {
786                 debugError("Could not add channel %s to StreamProcessor\n",
787                     channelInfo.name.c_str());
788                 continue;
789             }
790         }
791
792         if(!p->setDllBandwidth(recv_sp_dll_bw)) {
793             debugFatal("Could not set DLL bandwidth\n");
794             delete p;
795             return false;
796         }
797
798         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Receive SP on channel [%d audio, %d midi]\n", this, nb_audio, nb_midi);
799         // add the SP to the vector
800         m_receiveProcessors.push_back(p);
801     }
802
803     // prepare transmit SP's
804     names_audio.clear();
805     names_midi.clear();
806 //     for (unsigned int i=0;i<1;i++) {
807     for (unsigned int i=0; i<m_nb_rx; i++) {
808
809         // construct the streamprocessor
810         Streaming::StreamProcessor *p;
811         if(!readRxReg(i, DICE_REGISTER_RX_NB_AUDIO_BASE, &nb_audio)) {
812             debugError("Could not read DICE_REGISTER_RX_NB_AUDIO_BASE register for ARX%u\n", i);
813             continue;
814         }
815         if(!readRxReg(i, DICE_REGISTER_RX_MIDI_BASE, &nb_midi)) {
816             debugError("Could not read DICE_REGISTER_RX_MIDI_BASE register for ARX%u\n", i);
817             continue;
818         }
819
820         // request the channel names
821         names_audio = getRxNameString(i);
822
823         /* Vendor-specific hacks */
824         // PP: I think this was a workaround for a bug that is not required anymore
825         #if 0
826         if (FW_VENDORID_ALESIS == getConfigRom().getNodeVendorId()) {
827             /* Alesis io14 RX0 claims to have six audio channels. Ignore
828             * it, just use 8 for Bus1-L+R .. Bus4-L+R.
829             */
830             if (0x00000001 == getConfigRom().getModelId()) {
831                 nb_audio = 8;
832             }
833
834             /* Alesis Multimix16 RX0 only has two channels, Main-Out L+R */
835             if (0x00000000 == getConfigRom().getModelId()) {
836                 nb_audio = 2;
837             }
838         }
839         #endif
840
841         nb_channels = nb_audio;
842         if(nb_midi) nb_channels += 1; // midi-muxed counts as one
843
844         if (names_audio.size() != nb_audio) {
845             debugWarning("The audio channel name vector is incorrect, using default names\n");
846             names_audio.clear();
847
848             for (unsigned int j=0; j < nb_audio; j++) {
849                 std::ostringstream newname;
850                 newname << "output_" << j;
851                 names_audio.push_back(newname.str());
852             }
853         }
854
855         // construct the MIDI names
856         for (unsigned int j=0; j < nb_midi; j++) {
857             std::ostringstream newname;
858             newname << "midi_out_" << j;
859             names_midi.push_back(newname.str());
860         }
861
862         enum Streaming::Port::E_Direction port_type;
863         float dll_bw;
864         if (snoopMode) {
865             // we are snooping, so this is receive too.
866             p = new Streaming::AmdtpReceiveStreamProcessor(*this, nb_channels);
867             port_type = Streaming::Port::E_Capture;
868             dll_bw = recv_sp_dll_bw;
869         } else {
870             // this is a normal situation
871             Streaming::AmdtpTransmitStreamProcessor *t;
872             t = new Streaming::AmdtpTransmitStreamProcessor(*this, nb_channels);
873             #if AMDTP_ALLOW_PAYLOAD_IN_NODATA_XMIT
874             // the DICE-II cannot handle payload in the NO-DATA packets.
875             // the other DICE chips don't need payload. Therefore
876             // we disable it.
877             t->sendPayloadForNoDataPackets(false);
878             #endif
879    
880             // transmit control parameters
881             t->setMaxCyclesToTransmitEarly(xmit_max_cycles_early_transmit);
882             t->setTransferDelay(xmit_transfer_delay);
883             t->setMinCyclesBeforePresentation(xmit_min_cycles_before_presentation);
884
885             p = t;
886             port_type = Streaming::Port::E_Playback;
887             dll_bw = xmit_sp_dll_bw;
888         }
889
890         if(!p->init()) {
891             debugFatal("Could not initialize transmit processor %s!\n",
892                 (snoopMode?" in snoop mode":""));
893             delete p;
894             continue;
895         }
896
897         // add audio ports to the processor
898         for (unsigned int j=0; j < nb_audio; j++) {
899             diceChannelInfo channelInfo;
900             channelInfo.name = names_audio.at(j);
901             channelInfo.portType = ePT_Analog;
902             channelInfo.streamPosition = j;
903             channelInfo.streamLocation = 0;
904
905             if (!addChannelToProcessor(&channelInfo, p, port_type)) {
906                 debugError("Could not add channel %s to StreamProcessor\n",
907                     channelInfo.name.c_str());
908                 continue;
909             }
910         }
911
912         // add midi ports to the processor
913         for (unsigned int j=0; j < nb_midi; j++) {
914             diceChannelInfo channelInfo;
915             channelInfo.name = names_midi.at(j);
916             channelInfo.portType = ePT_MIDI;
917             channelInfo.streamPosition = nb_audio;
918             channelInfo.streamLocation = j;
919
920             if (!addChannelToProcessor(&channelInfo, p, port_type)) {
921                 debugError("Could not add channel %s to StreamProcessor\n",
922                     channelInfo.name.c_str());
923                 continue;
924             }
925         }
926
927         // set DLL bandwidth
928         if(!p->setDllBandwidth(recv_sp_dll_bw)) {
929             debugFatal("Could not set DLL bandwidth\n");
930             delete p;
931             return false;
932         }
933        
934         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Transmit SP on channel [%d audio, %d midi]%s\n",
935                                          this, nb_audio, nb_midi, (snoopMode?" snoop mode":""));
936
937         // we put this SP into the transmit SP vector,
938         // no matter if we are in snoop mode or not
939         // this allows us to find out what direction
940         // a certain stream should have.
941         m_transmitProcessors.push_back(p);
942     }
943     return true;
944 }
945
946 bool
947 Device::addChannelToProcessor(
948     diceChannelInfo *channelInfo,
949     Streaming::StreamProcessor *processor,
950     Streaming::Port::E_Direction direction) {
951
952     std::string id=std::string("dev?");
953     if(!getOption("id", id)) {
954         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
955     }
956
957     std::ostringstream portname;
958     portname << id;
959     if(direction == Streaming::Port::E_Playback) {
960         portname << "p";
961     } else {
962         portname << "c";
963     }
964
965     portname << "_" << channelInfo->name;
966
967     Streaming::Port *p=NULL;
968     switch(channelInfo->portType) {
969     case ePT_Analog:
970         p=new Streaming::AmdtpAudioPort(
971                 *processor,
972                 portname.str(),
973                 direction,
974                 channelInfo->streamPosition,
975                 channelInfo->streamLocation,
976                 Streaming::AmdtpPortInfo::E_MBLA
977         );
978         break;
979
980     case ePT_MIDI:
981         p=new Streaming::AmdtpMidiPort(
982                 *processor,
983                 portname.str(),
984                 direction,
985                 channelInfo->streamPosition,
986                 channelInfo->streamLocation,
987                 Streaming::AmdtpPortInfo::E_Midi
988         );
989
990         break;
991     default:
992     // unsupported
993         break;
994     }
995
996     if (!p) {
997         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->name.c_str());
998     }
999
1000     return true;
1001 }
1002
1003 bool
1004 Device::lock() {
1005     fb_octlet_t result;
1006
1007     debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device at node %d\n", getNodeId());
1008
1009     bool snoopMode = false;
1010     if(!getOption("snoopMode", snoopMode)) {
1011         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1012     }
1013
1014     if (snoopMode) {
1015         debugWarning("Lock not supported in snoop mode\n");
1016         return true; //FIXME: this should be false
1017     } else {
1018
1019     // get a notifier to handle device notifications
1020         nodeaddr_t notify_address;
1021         notify_address = get1394Service().findFreeARMBlock(
1022                             DICE_NOTIFIER_BASE_ADDRESS,
1023                             DICE_NOTIFIER_BLOCK_LENGTH,
1024                             DICE_NOTIFIER_BLOCK_LENGTH);
1025    
1026         if (notify_address == 0xFFFFFFFFFFFFFFFFLLU) {
1027             debugError("Could not find free ARM block for notification\n");
1028             return false;
1029         }
1030    
1031         m_notifier = new Device::Notifier(*this, notify_address);
1032    
1033         if(!m_notifier) {
1034             debugError("Could not allocate notifier\n");
1035             return false;
1036         }
1037    
1038         if (!get1394Service().registerARMHandler(m_notifier)) {
1039             debugError("Could not register notifier\n");
1040             delete m_notifier;
1041             m_notifier=NULL;
1042             return false;
1043         }
1044    
1045         // register this notifier
1046         fb_nodeaddr_t addr = DICE_REGISTER_BASE
1047                         + m_global_reg_offset
1048                         + DICE_REGISTER_GLOBAL_OWNER;
1049    
1050         // registry offsets should always be smaller than 0x7FFFFFFF
1051         // because otherwise base + offset > 64bit
1052         if(m_global_reg_offset & 0x80000000) {
1053             debugError("register offset not initialized yet\n");
1054             return false;
1055         }
1056    
1057         fb_nodeaddr_t swap_value = ((0xFFC0) | get1394Service().getLocalNodeId());
1058         swap_value = swap_value << 48;
1059         swap_value |= m_notifier->getStart();
1060    
1061         if (!get1394Service().lockCompareSwap64(getNodeId() | 0xFFC0,
1062                                                 addr, DICE_OWNER_NO_OWNER,
1063                                                 swap_value, &result )) {
1064             debugWarning("Could not register ourselves as device owner\n");
1065             return false;
1066         }
1067    
1068         if (result != DICE_OWNER_NO_OWNER) {
1069             debugWarning("Could not register ourselves as device owner, unexpected register value: 0x%016llX\n", result);
1070             return false;
1071         }
1072    
1073         return true;
1074     }
1075 }
1076
1077
1078 bool
1079 Device::unlock() {
1080     fb_octlet_t result;
1081
1082     bool snoopMode = false;
1083     if(!getOption("snoopMode", snoopMode)) {
1084         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1085     }
1086
1087     if (snoopMode) {
1088         debugWarning("Unlock not supported in snoop mode\n");
1089         return true; //FIXME: this should be false
1090     } else {
1091         if(!m_notifier) {
1092             debugWarning("Request to unlock, but no notifier present!\n");
1093             return false;
1094         }
1095    
1096         fb_nodeaddr_t addr = DICE_REGISTER_BASE
1097                         + m_global_reg_offset
1098                         + DICE_REGISTER_GLOBAL_OWNER;
1099    
1100         // registry offsets should always be smaller than 0x7FFFFFFF
1101         // because otherwise base + offset > 64bit
1102         if(m_global_reg_offset & 0x80000000) {
1103             debugError("register offset not initialized yet\n");
1104             return false;
1105         }
1106    
1107         fb_nodeaddr_t compare_value = ((0xFFC0) | get1394Service().getLocalNodeId());
1108         compare_value <<= 48;
1109         compare_value |= m_notifier->getStart();
1110    
1111         if (!get1394Service().lockCompareSwap64(  getNodeId() | 0xFFC0, addr, compare_value,
1112                                         DICE_OWNER_NO_OWNER, &result )) {
1113             debugWarning("Could not unregister ourselves as device owner\n");
1114             return false;
1115         }
1116    
1117         get1394Service().unregisterARMHandler(m_notifier);
1118         delete m_notifier;
1119         m_notifier=NULL;
1120    
1121         return true;
1122     }
1123 }
1124
1125 bool
1126 Device::enableStreaming() {
1127     bool snoopMode = false;
1128     if(!getOption("snoopMode", snoopMode)) {
1129         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1130     }
1131
1132     if (snoopMode) {
1133         debugWarning("Stream should be already running for snoop mode\n");
1134         return true;
1135     } else {
1136         return enableIsoStreaming();
1137     }
1138 }
1139
1140 bool
1141 Device::disableStreaming() {
1142     bool snoopMode = false;
1143     if(!getOption("snoopMode", snoopMode)) {
1144         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1145     }
1146
1147     if (snoopMode) {
1148         debugWarning("Won't disable stream in snoop mode\n");
1149         return true;
1150     } else {
1151         return disableIsoStreaming();
1152     }
1153 }
1154
1155 int
1156 Device::getStreamCount() {
1157     return m_receiveProcessors.size() + m_transmitProcessors.size();
1158 }
1159
1160 Streaming::StreamProcessor *
1161 Device::getStreamProcessorByIndex(int i) {
1162
1163     if (i<(int)m_receiveProcessors.size()) {
1164         return m_receiveProcessors.at(i);
1165     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1166         return m_transmitProcessors.at(i-m_receiveProcessors.size());
1167     }
1168
1169     return NULL;
1170 }
1171
1172 bool
1173 Device::startStreamByIndex(int i) {
1174     bool snoopMode = false;
1175     if(!getOption("snoopMode", snoopMode)) {
1176         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1177     }
1178
1179     if (!snoopMode && isIsoStreamingEnabled()) {
1180         debugError("Cannot start streams while streaming is enabled\n");
1181         return false;
1182     }
1183
1184     if (i<(int)m_receiveProcessors.size()) {
1185         int n=i;
1186         Streaming::StreamProcessor *p = m_receiveProcessors.at(n);
1187
1188         if(snoopMode) { // a stream from the device to another host
1189             fb_quadlet_t reg_isoch;
1190             // check value of ISO_CHANNEL register
1191             if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) {
1192                 debugError("Could not read ISO_CHANNEL register for ATX %d\n", n);
1193                 p->setChannel(-1);
1194                 return false;
1195             }
1196             int isochannel = reg_isoch;
1197             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Snooping RX from channel %d\n", isochannel);
1198             p->setChannel(isochannel);
1199         } else {
1200             // allocate ISO channel
1201             int isochannel = allocateIsoChannel(p->getMaxPacketSize());
1202             if(isochannel<0) {
1203                 debugError("Could not allocate iso channel for SP %d (ATX %d)\n",i,n);
1204                 return false;
1205             }
1206             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Allocated channel %lu for RX\n", isochannel);
1207             p->setChannel(isochannel);
1208    
1209             fb_quadlet_t reg_isoch;
1210             // check value of ISO_CHANNEL register
1211             if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) {
1212                 debugError("Could not read ISO_CHANNEL register for ATX %d\n", n);
1213                 p->setChannel(-1);
1214                 deallocateIsoChannel(isochannel);
1215                 return false;
1216             }
1217             if(reg_isoch != 0xFFFFFFFFUL) {
1218                 debugError("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08X) for ATX %d\n", reg_isoch, n);
1219                 p->setChannel(-1);
1220                 deallocateIsoChannel(isochannel);
1221                 return false;
1222             }
1223    
1224             // write value of ISO_CHANNEL register
1225             reg_isoch = isochannel;
1226             if(!writeTxReg(n, DICE_REGISTER_TX_ISOC_BASE, reg_isoch)) {
1227                 debugError("Could not write ISO_CHANNEL register for ATX %d\n", n);
1228                 p->setChannel(-1);
1229                 deallocateIsoChannel(isochannel);
1230                 return false;
1231             }
1232         }
1233         return true;
1234
1235     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1236         int n=i-m_receiveProcessors.size();
1237         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1238
1239         if(snoopMode) { // a stream from the device to another host
1240             fb_quadlet_t reg_isoch;
1241             // check value of ISO_CHANNEL register
1242             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1243                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1244                 p->setChannel(-1);
1245                 return false;
1246             }
1247             int isochannel = reg_isoch;
1248             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Snooping TX from channel %d\n", isochannel);
1249             p->setChannel(isochannel);
1250         } else {
1251             // allocate ISO channel
1252             int isochannel = allocateIsoChannel(p->getMaxPacketSize());
1253             if(isochannel<0) {
1254                 debugError("Could not allocate iso channel for SP %d (ARX %d)\n",i,n);
1255                 return false;
1256             }
1257             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Allocated channel %lu for TX\n", isochannel);
1258             p->setChannel(isochannel);
1259    
1260             fb_quadlet_t reg_isoch;
1261             // check value of ISO_CHANNEL register
1262             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1263                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1264                 p->setChannel(-1);
1265                 deallocateIsoChannel(isochannel);
1266                 return false;
1267             }
1268             if(reg_isoch != 0xFFFFFFFFUL) {
1269                 debugError("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08X) for ARX %d\n", reg_isoch, n);
1270                 p->setChannel(-1);
1271                 deallocateIsoChannel(isochannel);
1272                 return false;
1273             }
1274    
1275             // write value of ISO_CHANNEL register
1276             reg_isoch=isochannel;
1277             if(!writeRxReg(n, DICE_REGISTER_RX_ISOC_BASE, reg_isoch)) {
1278                 debugError("Could not write ISO_CHANNEL register for ARX %d\n", n);
1279                 p->setChannel(-1);
1280                 deallocateIsoChannel(isochannel);
1281                 return false;
1282             }
1283         }
1284         return true;
1285     }
1286
1287     debugError("SP index %d out of range!\n",i);
1288     return false;
1289 }
1290
1291 bool
1292 Device::stopStreamByIndex(int i) {
1293     bool snoopMode = false;
1294     if(!getOption("snoopMode", snoopMode)) {
1295         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1296     }
1297
1298     if (!snoopMode && isIsoStreamingEnabled()) {
1299         debugError("Cannot stop streams while streaming is enabled\n");
1300         return false;
1301     }
1302
1303     if (i<(int)m_receiveProcessors.size()) {
1304         int n=i;
1305         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
1306         if(snoopMode) { // a stream from the device to another host
1307             // nothing to do
1308         } else {
1309             unsigned int isochannel = p->getChannel();
1310    
1311             fb_quadlet_t reg_isoch;
1312             // check value of ISO_CHANNEL register
1313             if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) {
1314                 debugError("Could not read ISO_CHANNEL register for ATX %d\n", n);
1315                 return false;
1316             }
1317             if(reg_isoch != isochannel) {
1318                 debugError("ISO_CHANNEL register != 0x%08X (=0x%08X) for ATX %d\n", isochannel, reg_isoch, n);
1319                 return false;
1320             }
1321    
1322             // write value of ISO_CHANNEL register
1323             reg_isoch=0xFFFFFFFFUL;
1324             if(!writeTxReg(n, DICE_REGISTER_TX_ISOC_BASE, reg_isoch)) {
1325                 debugError("Could not write ISO_CHANNEL register for ATX %d\n", n);
1326                 return false;
1327             }
1328    
1329             // deallocate ISO channel
1330             if(!deallocateIsoChannel(isochannel)) {
1331                 debugError("Could not deallocate iso channel for SP %d (ATX %d)\n",i,n);
1332                 return false;
1333             }
1334         }
1335         p->setChannel(-1);
1336         return true;
1337
1338     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1339         int n=i-m_receiveProcessors.size();
1340         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1341
1342         if(snoopMode) { // a stream from the device to another host
1343             // nothing to do
1344         } else {
1345             unsigned int isochannel = p->getChannel();
1346    
1347             fb_quadlet_t reg_isoch;
1348             // check value of ISO_CHANNEL register
1349             if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) {
1350                 debugError("Could not read ISO_CHANNEL register for ARX %d\n", n);
1351                 return false;
1352             }
1353             if(reg_isoch != isochannel) {
1354                 debugError("ISO_CHANNEL register != 0x%08X (=0x%08X) for ARX %d\n", isochannel, reg_isoch, n);
1355                 return false;
1356             }
1357    
1358             // write value of ISO_CHANNEL register
1359             reg_isoch=0xFFFFFFFFUL;
1360             if(!writeRxReg(n, DICE_REGISTER_RX_ISOC_BASE, reg_isoch)) {
1361                 debugError("Could not write ISO_CHANNEL register for ARX %d\n", n);
1362                 return false;
1363             }
1364    
1365             // deallocate ISO channel
1366             if(!deallocateIsoChannel(isochannel)) {
1367                 debugError("Could not deallocate iso channel for SP %d (ARX %d)\n",i,n);
1368                 return false;
1369             }
1370         }
1371
1372         p->setChannel(-1);
1373         return true;
1374     }
1375
1376     debugError("SP index %d out of range!\n",i);
1377
1378     return false;
1379 }
1380
1381 // helper routines
1382
1383 // allocate ISO resources for the SP's
1384 int Device::allocateIsoChannel(unsigned int packet_size) {
1385     unsigned int bandwidth=8+packet_size;
1386
1387     int ch=get1394Service().allocateIsoChannelGeneric(bandwidth);
1388
1389     debugOutput(DEBUG_LEVEL_VERBOSE, "allocated channel %d, bandwidth %d\n",
1390         ch, bandwidth);
1391
1392     return ch;
1393 }
1394 // deallocate ISO resources
1395 bool Device::deallocateIsoChannel(int channel) {
1396     debugOutput(DEBUG_LEVEL_VERBOSE, "freeing channel %d\n",channel);
1397     return get1394Service().freeIsoChannel(channel);
1398 }
1399
1400 bool
1401 Device::enableIsoStreaming() {
1402     return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_ENABLE);
1403 }
1404
1405 bool
1406 Device::disableIsoStreaming() {
1407     return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_DISABLE);
1408 }
1409
1410 bool
1411 Device::isIsoStreamingEnabled() {
1412     fb_quadlet_t result;
1413     readGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, &result);
1414     // I don't know what exactly is 'enable',
1415     // but disable is definately == 0
1416     return (result != DICE_ISOSTREAMING_DISABLE);
1417 }
1418
1419 /**
1420  * @brief performs a masked bit register equals 0 check on the global parameter space
1421  * @return true if readGlobalReg(offset) & mask == 0
1422  */
1423 bool
1424 Device::maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) {
1425     fb_quadlet_t result;
1426     readGlobalReg(offset, &result);
1427     return ((result & mask) == 0);
1428 }
1429 /**
1430  * @brief performs a masked bit register not equal to 0 check on the global parameter space
1431  * @return true if readGlobalReg(offset) & mask != 0
1432  */
1433 bool
1434 Device::maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) {
1435     return !maskedCheckZeroGlobalReg(offset, mask);
1436 }
1437
1438 Device::diceNameVector
1439 Device::getTxNameString(unsigned int i) {
1440     diceNameVector names;
1441     char namestring[DICE_TX_NAMES_SIZE+1];
1442
1443     if (!readTxRegBlock(i, DICE_REGISTER_TX_NAMES_BASE,
1444                         (fb_quadlet_t *)namestring, DICE_TX_NAMES_SIZE)) {
1445         debugError("Could not read TX name string \n");
1446         return names;
1447     }
1448
1449     // Strings from the device are always little-endian,
1450     // so byteswap for big-endian machines
1451     #if __BYTE_ORDER == __BIG_ENDIAN
1452     byteSwapBlock((quadlet_t *)namestring, DICE_TX_NAMES_SIZE/4);
1453     #endif
1454     namestring[DICE_TX_NAMES_SIZE]='\0';
1455     return splitNameString(std::string(namestring));
1456 }
1457
1458 Device::diceNameVector
1459 Device::getRxNameString(unsigned int i) {
1460     diceNameVector names;
1461     char namestring[DICE_RX_NAMES_SIZE+1];
1462
1463     if (!readRxRegBlock(i, DICE_REGISTER_RX_NAMES_BASE,
1464                         (fb_quadlet_t *)namestring, DICE_RX_NAMES_SIZE)) {
1465         debugError("Could not read RX name string \n");
1466         return names;
1467     }
1468
1469     // Strings from the device are always little-endian,
1470     // so byteswap for big-endian machines
1471     #if __BYTE_ORDER == __BIG_ENDIAN
1472     byteSwapBlock((quadlet_t *)namestring, DICE_RX_NAMES_SIZE/4);
1473     #endif
1474     namestring[DICE_RX_NAMES_SIZE]='\0';
1475     return splitNameString(std::string(namestring));
1476 }
1477
1478 Device::diceNameVector
1479 Device::getClockSourceNameString() {
1480     diceNameVector names;
1481     char namestring[DICE_CLOCKSOURCENAMES_SIZE+1];
1482
1483     if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_CLOCKSOURCENAMES,
1484                       (fb_quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE)) {
1485         debugError("Could not read CLOCKSOURCE name string \n");
1486         return names;
1487     }
1488
1489     // Strings from the device are always little-endian,
1490     // so byteswap for big-endian machines
1491     #if __BYTE_ORDER == __BIG_ENDIAN
1492     byteSwapBlock((quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE/4);
1493     #endif
1494     namestring[DICE_CLOCKSOURCENAMES_SIZE]='\0';
1495     return splitNameString(std::string(namestring));
1496 }
1497
1498 std::string
1499 Device::getDeviceNickName() {
1500     char namestring[DICE_NICK_NAME_SIZE+1];
1501
1502     if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_NICK_NAME,
1503                         (fb_quadlet_t *)namestring, DICE_NICK_NAME_SIZE)) {
1504         debugError("Could not read nickname string \n");
1505         return std::string("(unknown)");
1506     }
1507
1508     // Strings from the device are always little-endian,
1509     // so byteswap for big-endian machines
1510     #if __BYTE_ORDER == __BIG_ENDIAN
1511     byteSwapBlock((quadlet_t *)namestring, DICE_NICK_NAME_SIZE/4);
1512     #endif
1513     namestring[DICE_NICK_NAME_SIZE]='\0';
1514     return std::string(namestring);
1515 }
1516
1517 bool
1518 Device::setDeviceNickName(std::string name) {
1519     char namestring[DICE_NICK_NAME_SIZE+1];
1520     strncpy(namestring, name.c_str(), DICE_NICK_NAME_SIZE);
1521
1522     // Strings from the device are always little-endian,
1523     // so byteswap for big-endian machines
1524     #if __BYTE_ORDER == __BIG_ENDIAN
1525     byteSwapBlock((quadlet_t *)namestring, DICE_NICK_NAME_SIZE/4);
1526     #endif
1527
1528     if (!writeGlobalRegBlock(DICE_REGISTER_GLOBAL_NICK_NAME,
1529                         (fb_quadlet_t *)namestring, DICE_NICK_NAME_SIZE)) {
1530         debugError("Could not write nickname string \n");
1531         return false;
1532     }
1533     return true;
1534 }
1535
1536 Device::diceNameVector
1537 Device::splitNameString(std::string in) {
1538     diceNameVector names;
1539
1540     // find the end of the string
1541     string::size_type end = in.find(string("\\\\"));
1542     // cut the end
1543     in = in.substr(0,end);
1544
1545     string::size_type cut;
1546     while( (cut = in.find(string("\\"))) != in.npos ) {
1547         if(cut > 0) {
1548             names.push_back(in.substr(0,cut));
1549         }
1550         in = in.substr(cut+1);
1551     }
1552     if(in.length() > 0) {
1553         names.push_back(in);
1554     }
1555     return names;
1556 }
1557
1558
1559 // I/O routines
1560 bool
1561 Device::initIoFunctions() {
1562
1563     // offsets and sizes are returned in quadlets, but we use byte values
1564     if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_OFF, &m_global_reg_offset)) {
1565         debugError("Could not initialize m_global_reg_offset\n");
1566         return false;
1567     }
1568     m_global_reg_offset*=4;
1569
1570     if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_SZ, &m_global_reg_size)) {
1571         debugError("Could not initialize m_global_reg_size\n");
1572         return false;
1573     }
1574     m_global_reg_size*=4;
1575
1576     if(!readReg(DICE_REGISTER_TX_PAR_SPACE_OFF, &m_tx_reg_offset)) {
1577         debugError("Could not initialize m_tx_reg_offset\n");
1578         return false;
1579     }
1580     m_tx_reg_offset*=4;
1581
1582     if(!readReg(DICE_REGISTER_TX_PAR_SPACE_SZ, &m_tx_reg_size)) {
1583         debugError("Could not initialize m_tx_reg_size\n");
1584         return false;
1585     }
1586     m_tx_reg_size*=4;
1587
1588     if(!readReg(DICE_REGISTER_RX_PAR_SPACE_OFF, &m_rx_reg_offset)) {
1589         debugError("Could not initialize m_rx_reg_offset\n");
1590         return false;
1591     }
1592     m_rx_reg_offset*=4;
1593
1594     if(!readReg(DICE_REGISTER_RX_PAR_SPACE_SZ, &m_rx_reg_size)) {
1595         debugError("Could not initialize m_rx_reg_size\n");
1596         return false;
1597     }
1598     m_rx_reg_size*=4;
1599
1600     if(!readReg(DICE_REGISTER_UNUSED1_SPACE_OFF, &m_unused1_reg_offset)) {
1601         debugError("Could not initialize m_unused1_reg_offset\n");
1602         return false;
1603     }
1604     m_unused1_reg_offset*=4;
1605
1606     if(!readReg(DICE_REGISTER_UNUSED1_SPACE_SZ, &m_unused1_reg_size)) {
1607         debugError("Could not initialize m_unused1_reg_size\n");
1608         return false;
1609     }
1610     m_unused1_reg_size*=4;
1611
1612     if(!readReg(DICE_REGISTER_UNUSED2_SPACE_OFF, &m_unused2_reg_offset)) {
1613         debugError("Could not initialize m_unused2_reg_offset\n");
1614         return false;
1615     }
1616     m_unused2_reg_offset*=4;
1617
1618     if(!readReg(DICE_REGISTER_UNUSED2_SPACE_SZ, &m_unused2_reg_size)) {
1619         debugError("Could not initialize m_unused2_reg_size\n");
1620         return false;
1621     }
1622     m_unused2_reg_size*=4;
1623
1624     if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_NB_TX, &m_nb_tx)) {
1625         debugError("Could not initialize m_nb_tx\n");
1626         return false;
1627     }
1628     if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_SZ_TX, &m_tx_size)) {
1629         debugError("Could not initialize m_tx_size\n");
1630         return false;
1631     }
1632     m_tx_size*=4;
1633
1634     if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_NB_RX, &m_nb_rx)) {
1635         debugError("Could not initialize m_nb_rx\n");
1636         return false;
1637     }
1638
1639     // FIXME: verify this and clean it up.
1640     /* special case for Alesis io14, which announces two receive transmitters,
1641      * but only has one. Same is true for Alesis Multimix16.
1642      */
1643     if (FW_VENDORID_ALESIS == getConfigRom().getNodeVendorId()) {
1644         /* we may want to use a switch-case-statement some day... */
1645         if ((0x00000001 == getConfigRom().getModelId()) ||
1646             (0x00000000 == getConfigRom().getModelId())) {
1647             m_nb_rx = 1;
1648         }
1649     }
1650
1651     if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_SZ_RX, &m_rx_size)) {
1652         debugError("Could not initialize m_rx_size\n");
1653         return false;
1654     }
1655     m_rx_size*=4;
1656
1657     debugOutput(DEBUG_LEVEL_VERBOSE,"DICE Parameter Space info:\n");
1658     debugOutput(DEBUG_LEVEL_VERBOSE," Global  : offset=%04X size=%04d\n", m_global_reg_offset, m_global_reg_size);
1659     debugOutput(DEBUG_LEVEL_VERBOSE," TX      : offset=%04X size=%04d\n", m_tx_reg_offset, m_tx_reg_size);
1660     debugOutput(DEBUG_LEVEL_VERBOSE,"               nb=%4d size=%04d\n", m_nb_tx, m_tx_size);
1661     debugOutput(DEBUG_LEVEL_VERBOSE," RX      : offset=%04X size=%04d\n", m_rx_reg_offset, m_rx_reg_size);
1662     debugOutput(DEBUG_LEVEL_VERBOSE,"               nb=%4d size=%04d\n", m_nb_rx, m_rx_size);
1663     debugOutput(DEBUG_LEVEL_VERBOSE," UNUSED1 : offset=%04X size=%04d\n", m_unused1_reg_offset, m_unused1_reg_size);
1664     debugOutput(DEBUG_LEVEL_VERBOSE," UNUSED2 : offset=%04X size=%04d\n", m_unused2_reg_offset, m_unused2_reg_size);
1665
1666     return true;
1667 }
1668
1669 bool
1670 Device::readReg(fb_nodeaddr_t offset, fb_quadlet_t *result) {
1671     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading base register offset 0x%08llX\n", offset);
1672
1673     if(offset >= DICE_INVALID_OFFSET) {
1674         debugError("invalid offset: 0x%016llX\n", offset);
1675         return false;
1676     }
1677
1678     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1679     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1680
1681     if(!get1394Service().read_quadlet( nodeId, addr, result ) ) {
1682         debugError("Could not read from node 0x%04X addr 0x%012X\n", nodeId, addr);
1683         return false;
1684     }
1685
1686     *result = CondSwapFromBus32(*result);
1687
1688     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Read result: 0x%08X\n", *result);
1689
1690     return true;
1691 }
1692
1693 bool
1694 Device::writeReg(fb_nodeaddr_t offset, fb_quadlet_t data) {
1695     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08llX, data: 0x%08X\n",
1696         offset, data);
1697
1698     if(offset >= DICE_INVALID_OFFSET) {
1699         debugError("invalid offset: 0x%016llX\n", offset);
1700         return false;
1701     }
1702
1703     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1704     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1705
1706     if(!get1394Service().write_quadlet( nodeId, addr, CondSwapToBus32(data) ) ) {
1707         debugError("Could not write to node 0x%04X addr 0x%012X\n", nodeId, addr);
1708         return false;
1709     }
1710     return true;
1711 }
1712
1713 bool
1714 Device::readRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1715     debugOutput(DEBUG_LEVEL_VERBOSE,"Reading base register offset 0x%08llX, length %u, to %p\n",
1716         offset, length, data);
1717     const int blocksize_quads = 512/4;
1718
1719     if(offset >= DICE_INVALID_OFFSET) {
1720         debugError("invalid offset: 0x%016llX\n", offset);
1721         return false;
1722     }
1723
1724     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1725     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1726     int quads_done = 0;
1727     // round to next full quadlet
1728     int length_quads = (length+3)/4;
1729     while(quads_done < length_quads) {
1730         fb_nodeaddr_t curr_addr = addr + quads_done*4;
1731         fb_quadlet_t *curr_data = data + quads_done;
1732         int quads_todo = length_quads - quads_done;
1733         debugOutput(DEBUG_LEVEL_VERBOSE, "reading addr: 0x%016llX, %d quads to %p\n", curr_addr, quads_todo, curr_data);
1734        
1735         if (quads_todo > blocksize_quads) {
1736             debugOutput(DEBUG_LEVEL_VERBOSE, "Truncating read from %d to %d quadlets\n", quads_todo, blocksize_quads);
1737             quads_todo = blocksize_quads;
1738         }
1739         #ifdef DEBUG
1740         if (quads_todo < 0) {
1741             debugError("BUG: quads_todo < 0: %d\n", quads_todo);
1742         }
1743         #endif
1744
1745         if(!get1394Service().read( nodeId, curr_addr, quads_todo, curr_data ) ) {
1746             debugError("Could not read %d quadlets from node 0x%04X addr 0x%012llX\n", nodeId, quads_todo, curr_addr);
1747             return false;
1748         }
1749         quads_done += quads_todo;
1750     }
1751
1752     byteSwapFromBus(data, length/4);
1753     return true;
1754 }
1755
1756 bool
1757 Device::writeRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1758     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08llX, length: %u\n",
1759         offset, length);
1760     const int blocksize_quads = 512/4;
1761
1762     if(offset >= DICE_INVALID_OFFSET) {
1763         debugError("invalid offset: 0x%016llX\n", offset);
1764         return false;
1765     }
1766
1767     fb_quadlet_t data_out[length/4];
1768     memcpy(data_out, data, length);
1769     byteSwapToBus(data_out, length/4);
1770
1771     fb_nodeaddr_t addr = DICE_REGISTER_BASE + offset;
1772     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
1773     int quads_done = 0;
1774     int length_quads = (length+3)/4;
1775     while(quads_done < length_quads) {
1776         fb_nodeaddr_t curr_addr = addr + quads_done*4;
1777         fb_quadlet_t *curr_data = data_out + quads_done;
1778         int quads_todo = length_quads - quads_done;
1779         if (quads_todo > blocksize_quads) {
1780             debugOutput(DEBUG_LEVEL_VERBOSE, "Truncating write from %d to %d quadlets\n", quads_todo, blocksize_quads);
1781             quads_todo = blocksize_quads;
1782         }
1783         #ifdef DEBUG
1784         if (quads_todo < 0) {
1785             debugError("BUG: quads_todo < 0: %d\n", quads_todo);
1786         }
1787         #endif
1788
1789         if(!get1394Service().write( nodeId, addr, quads_todo, curr_data ) ) {
1790             debugError("Could not write %d quadlets to node 0x%04X addr 0x%012llX\n", nodeId, quads_todo, curr_addr);
1791             return false;
1792         }
1793         quads_done += quads_todo;
1794     }
1795
1796     return true;
1797 }
1798
1799 bool
1800 Device::readGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t *result) {
1801     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register offset 0x%04llX\n", offset);
1802
1803     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, sizeof(fb_quadlet_t));
1804     return readReg(m_global_reg_offset + offset_gl, result);
1805 }
1806
1807 bool
1808 Device::writeGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t data) {
1809     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register offset 0x%08llX, data: 0x%08X\n",
1810         offset, data);
1811
1812     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, sizeof(fb_quadlet_t));
1813     return writeReg(m_global_reg_offset + offset_gl, data);
1814 }
1815
1816 bool
1817 Device::readGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1818     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register block offset 0x%04llX, length %u bytes\n",
1819         offset, length);
1820
1821     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, length);
1822     return readRegBlock(m_global_reg_offset + offset_gl, data, length);
1823 }
1824
1825 bool
1826 Device::writeGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1827     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register block offset 0x%04llX, length %u bytes\n",
1828         offset, length);
1829
1830     fb_nodeaddr_t offset_gl = globalOffsetGen(offset, length);
1831     return writeRegBlock(m_global_reg_offset + offset_gl, data, length);
1832 }
1833
1834 fb_nodeaddr_t
1835 Device::globalOffsetGen(fb_nodeaddr_t offset, size_t length) {
1836
1837     // registry offsets should always be smaller than 0x7FFFFFFF
1838     // because otherwise base + offset > 64bit
1839     if(m_global_reg_offset & 0x80000000) {
1840         debugError("register offset not initialized yet\n");
1841         return DICE_INVALID_OFFSET;
1842     }
1843     // out-of-range check
1844     if(offset+length > m_global_reg_offset+m_global_reg_size) {
1845         debugError("register offset+length too large: 0x%0llX\n", offset + length);
1846         return DICE_INVALID_OFFSET;
1847     }
1848
1849     return offset;
1850 }
1851
1852 bool
1853 Device::readTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) {
1854     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Reading tx %d register offset 0x%04llX\n", i, offset);
1855
1856     fb_nodeaddr_t offset_tx = txOffsetGen(i, offset, sizeof(fb_quadlet_t));
1857     return readReg(m_tx_reg_offset + offset_tx, result);
1858 }
1859
1860 bool
1861 Device::writeTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) {
1862     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing tx %d register offset 0x%08llX, data: 0x%08X\n",
1863         i, offset, data);
1864
1865     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, sizeof(fb_quadlet_t));
1866     return writeReg(m_tx_reg_offset + offset_tx, data);
1867 }
1868
1869 bool
1870 Device::readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1871     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04llX, length %u bytes\n",
1872         offset, length);
1873
1874     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length);
1875     return readRegBlock(m_tx_reg_offset + offset_tx, data, length);
1876 }
1877
1878 bool
1879 Device::writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1880     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04llX, length %u bytes\n",
1881         offset, length);
1882
1883     fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length);
1884     return writeRegBlock(m_tx_reg_offset + offset_tx, data, length);
1885 }
1886
1887 fb_nodeaddr_t
1888 Device::txOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) {
1889     // registry offsets should always be smaller than 0x7FFFFFFF
1890     // because otherwise base + offset > 64bit
1891     if(m_tx_reg_offset & 0x80000000) {
1892         debugError("register offset not initialized yet\n");
1893         return DICE_INVALID_OFFSET;
1894     }
1895     if(m_nb_tx & 0x80000000) {
1896         debugError("m_nb_tx not initialized yet\n");
1897         return DICE_INVALID_OFFSET;
1898     }
1899     if(m_tx_size & 0x80000000) {
1900         debugError("m_tx_size not initialized yet\n");
1901         return DICE_INVALID_OFFSET;
1902     }
1903     if(i >= m_nb_tx) {
1904         debugError("TX index out of range\n");
1905         return DICE_INVALID_OFFSET;
1906     }
1907
1908     fb_nodeaddr_t offset_tx = DICE_REGISTER_TX_PARAM(m_tx_size, i, offset);
1909
1910     // out-of-range check
1911     if(offset_tx + length > m_tx_reg_offset+4+m_tx_reg_size*m_nb_tx) {
1912         debugError("register offset+length too large: 0x%0llX\n", offset_tx + length);
1913         return DICE_INVALID_OFFSET;
1914     }
1915
1916     return offset_tx;
1917 }
1918
1919 bool
1920 Device::readRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) {
1921     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx %d register offset 0x%04llX\n", i, offset);
1922
1923     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t));
1924     return readReg(m_rx_reg_offset + offset_rx, result);
1925 }
1926
1927 bool
1928 Device::writeRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) {
1929     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register offset 0x%08llX, data: 0x%08X\n",
1930         offset, data);
1931
1932     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t));
1933     return writeReg(m_rx_reg_offset + offset_rx, data);
1934 }
1935
1936 bool
1937 Device::readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1938     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04llX, length %u bytes\n",
1939         offset, length);
1940
1941     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length);
1942     return readRegBlock(m_rx_reg_offset + offset_rx, data, length);
1943 }
1944
1945 bool
1946 Device::writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) {
1947     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04llX, length %u bytes\n",
1948         offset, length);
1949
1950     fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length);
1951     return writeRegBlock(m_rx_reg_offset + offset_rx, data, length);
1952 }
1953
1954 fb_nodeaddr_t
1955 Device::rxOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) {
1956     // registry offsets should always be smaller than 0x7FFFFFFF
1957     // because otherwise base + offset > 64bit
1958     if(m_rx_reg_offset & 0x80000000) {
1959         debugError("register offset not initialized yet\n");
1960         return DICE_INVALID_OFFSET;
1961     }
1962     if(m_nb_rx & 0x80000000) {
1963         debugError("m_nb_rx not initialized yet\n");
1964         return DICE_INVALID_OFFSET;
1965     }
1966     if(m_rx_size & 0x80000000) {
1967         debugError("m_rx_size not initialized yet\n");
1968         return DICE_INVALID_OFFSET;
1969     }
1970     if(i >= m_nb_rx) {
1971         debugError("RX index out of range\n");
1972         return DICE_INVALID_OFFSET;
1973     }
1974
1975     fb_nodeaddr_t offset_rx = DICE_REGISTER_RX_PARAM(m_rx_size, i, offset);
1976
1977     // out-of-range check
1978     if(offset_rx + length > m_rx_reg_offset+4+m_rx_reg_size*m_nb_rx) {
1979         debugError("register offset+length too large: 0x%0llX\n", offset_rx + length);
1980         return DICE_INVALID_OFFSET;
1981     }
1982     return offset_rx;
1983 }
1984
1985
1986 // the notifier
1987
1988 Device::Notifier::Notifier(Device &d, nodeaddr_t start)
1989  : ARMHandler(d.get1394Service(), start, DICE_NOTIFIER_BLOCK_LENGTH,
1990               RAW1394_ARM_READ | RAW1394_ARM_WRITE | RAW1394_ARM_LOCK,
1991               RAW1394_ARM_WRITE, 0)
1992  , m_device(d)
1993 {
1994     // switch over the debug module to that of this device instead of the 1394 service
1995     m_debugModule = d.m_debugModule;
1996 }
1997
1998 Device::Notifier::~Notifier()
1999 {
2000
2001 }
2002
2003 }
Note: See TracBrowser for help on using the browser.