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

Revision 2803, 71.9 kB (checked in by jwoithe, 1 year ago)

Cosmetic: capitalise "L" in "Linux".

"Linux" is a proper noun so it should start with a capital letter. These
changes are almost all within comments.

This patch was originally proposed by pander on the ffado-devel mailing
list. It has been expanded to cover all similar cases to maintain
consistency throughout the source tree.

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