Changeset 408

Show
Ignore:
Timestamp:
02/20/07 09:21:31 (17 years ago)
Author:
pieterpalmers
Message:

- Implemented a mechanism to allocate and deallocate iso channels in a generic manner, being by cmp or otherwise.

- cleaned all commented out code from RME, as it is getting increasingly outdated.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/streaming-rework/src/bebob/bebob_avdevice.cpp

    r407 r408  
    11121112 
    11131113#ifdef TEST_XMIT_ONLY 
     1114 
     1115#else 
    11141116int 
    11151117AvDevice::getStreamCount() { 
    1116 //     return 2; // one receive, one transmit 
    1117     return 1; // one receive, one transmit 
     1118    return 2; // one receive, one transmit 
    11181119} 
    11191120 
     
    11221123    switch (i) { 
    11231124    case 0: 
    1124 //         return m_receiveProcessor; 
    1125 //     case 1: 
     1125        return m_receiveProcessor; 
     1126    case 1: 
    11261127//         if (m_snoopMode) { 
    11271128//             return m_receiveProcessor2; 
     
    11381139int 
    11391140AvDevice::startStreamByIndex(int i) { 
    1140     int iso_channel=0; 
    1141     int plug=0; 
    1142     int hostplug=-1; 
     1141    int iso_channel=-1; 
    11431142 
    11441143//     if (m_snoopMode) { 
     
    11711170        switch (i) { 
    11721171        case 0: 
    1173 //             // do connection management: make connection 
    1174 //             iso_channel = iec61883_cmp_connect( 
    1175 //                 m_p1394Service->getHandle(), 
    1176 //                 m_pConfigRom->getNodeId() | 0xffc0, 
    1177 //                 &plug, 
    1178 //                 raw1394_get_local_id (m_p1394Service->getHandle()), 
    1179 //                 &hostplug, 
    1180 //                 &m_receiveProcessorBandwidth); 
    1181 //  
    1182 //             // set the channel obtained by the connection management 
    1183 //             m_receiveProcessor->setChannel(iso_channel); 
    1184 //             break; 
    1185 //         case 1: 
    1186             // do connection management: make connection 
    1187             iso_channel = iec61883_cmp_connect( 
    1188                 m_p1394Service->getHandle(), 
    1189                 raw1394_get_local_id (m_p1394Service->getHandle()), 
    1190                 &hostplug, 
    1191                 m_pConfigRom->getNodeId() | 0xffc0, 
    1192                 &plug, 
    1193                 &m_transmitProcessorBandwidth); 
    1194  
    1195             // set the channel obtained by the connection management 
     1172            iso_channel=m_p1394Service->allocateIsoChannelCMP( 
     1173                m_pConfigRom->getNodeId() | 0xffc0, 0,  
     1174                m_p1394Service->getLocalNodeId()| 0xffc0, -1); 
     1175             
     1176            m_receiveProcessor->setChannel(iso_channel); 
     1177            break; 
     1178             
     1179        case 1: 
     1180            iso_channel=m_p1394Service->allocateIsoChannelCMP( 
     1181                m_p1394Service->getLocalNodeId()| 0xffc0, -1, 
     1182                m_pConfigRom->getNodeId() | 0xffc0, 0); 
     1183 
    11961184            m_transmitProcessor->setChannel(iso_channel); 
    11971185            break; 
     
    12301218        switch (i) { 
    12311219        case 0: 
    1232 //             // do connection management: break connection 
    1233 //             iec61883_cmp_disconnect( 
    1234 //                 m_p1394Service->getHandle(), 
    1235 //                 m_pConfigRom->getNodeId() | 0xffc0, 
    1236 //                 plug, 
    1237 //                 raw1394_get_local_id (m_p1394Service->getHandle()), 
    1238 //                 hostplug, 
    1239 //                 m_receiveProcessor->getChannel(), 
    1240 //                 m_receiveProcessorBandwidth); 
    1241 //  
    1242 //             break; 
    1243 //         case 1: 
    1244             // do connection management: break connection 
    1245             iec61883_cmp_disconnect( 
    1246                 m_p1394Service->getHandle(), 
    1247                 raw1394_get_local_id (m_p1394Service->getHandle()), 
    1248                 hostplug, 
    1249                 m_pConfigRom->getNodeId() | 0xffc0, 
    1250                 plug, 
    1251                 m_transmitProcessor->getChannel(), 
    1252                 m_transmitProcessorBandwidth); 
    1253  
     1220            m_p1394Service->freeIsoChannel(m_receiveProcessor->getChannel()); 
    12541221            break; 
    1255         default: 
    1256             return 0; 
    1257         } 
    1258 //     } 
    1259  
    1260     return 0; 
    1261 
    1262 #else 
    1263 int 
    1264 AvDevice::getStreamCount() { 
    1265     return 2; // one receive, one transmit 
    1266 
    1267  
    1268 FreebobStreaming::StreamProcessor * 
    1269 AvDevice::getStreamProcessorByIndex(int i) { 
    1270     switch (i) { 
    1271     case 0: 
    1272         return m_receiveProcessor; 
    1273     case 1: 
    1274 //         if (m_snoopMode) { 
    1275 //             return m_receiveProcessor2; 
    1276 //         } else { 
    1277             return m_transmitProcessor; 
    1278 //         } 
    1279     default: 
    1280         return NULL; 
    1281     } 
    1282     return 0; 
    1283 
    1284  
    1285 // FIXME: error checking 
    1286 int 
    1287 AvDevice::startStreamByIndex(int i) { 
    1288     int iso_channel=0; 
    1289     int plug=0; 
    1290     int hostplug=-1; 
    1291  
    1292 //     if (m_snoopMode) { 
    1293 // 
    1294 //         switch (i) { 
    1295 //         case 0: 
    1296 //             // snooping doesn't use CMP, but obtains the info of the channel 
    1297 //             // from the target plug 
    1298 // 
    1299 //             // TODO: get isochannel from plug 
    1300 // 
    1301 //             // set the channel obtained by the connection management 
    1302 //             m_receiveProcessor->setChannel(iso_channel); 
    1303 //             break; 
    1304 //         case 1: 
    1305 //             // snooping doesn't use CMP, but obtains the info of the channel 
    1306 //             // from the target plug 
    1307 // 
    1308 //             // TODO: get isochannel from plug 
    1309 // 
    1310 //             // set the channel obtained by the connection management 
    1311 //             m_receiveProcessor2->setChannel(iso_channel); 
    1312 // 
    1313 //             break; 
    1314 //         default: 
    1315 //             return 0; 
    1316 //         } 
    1317 //     } else { 
    1318  
    1319         switch (i) { 
    1320         case 0: 
    1321             // do connection management: make connection 
    1322             iso_channel = iec61883_cmp_connect( 
    1323                 m_p1394Service->getHandle(), 
    1324                 m_pConfigRom->getNodeId() | 0xffc0, 
    1325                 &plug, 
    1326                 raw1394_get_local_id (m_p1394Service->getHandle()), 
    1327                 &hostplug, 
    1328                 &m_receiveProcessorBandwidth); 
    1329  
    1330             // set the channel obtained by the connection management 
    1331             m_receiveProcessor->setChannel(iso_channel); 
     1222             
     1223        case 1: 
     1224            m_p1394Service->freeIsoChannel(m_transmitProcessor->getChannel()); 
    13321225            break; 
    1333         case 1: 
    1334             // do connection management: make connection 
    1335             iso_channel = iec61883_cmp_connect( 
    1336                 m_p1394Service->getHandle(), 
    1337                 raw1394_get_local_id (m_p1394Service->getHandle()), 
    1338                 &hostplug, 
    1339                 m_pConfigRom->getNodeId() | 0xffc0, 
    1340                 &plug, 
    1341                 &m_transmitProcessorBandwidth); 
    1342  
    1343             // set the channel obtained by the connection management 
    1344             m_transmitProcessor->setChannel(iso_channel); 
    1345             break; 
    1346         default: 
    1347             return -1; 
    1348         } 
    1349 //     } 
    1350  
    1351     if (iso_channel < 0) return -1; 
    1352      
    1353     return 0; 
    1354  
    1355 
    1356  
    1357 // FIXME: error checking 
    1358 int 
    1359 AvDevice::stopStreamByIndex(int i) { 
    1360     // do connection management: break connection 
    1361  
    1362     int plug=0; 
    1363     int hostplug=-1; 
    1364 //     if (m_snoopMode) { 
    1365 //         switch (i) { 
    1366 //         case 0: 
    1367 //             // do connection management: break connection 
    1368 // 
    1369 //             break; 
    1370 //         case 1: 
    1371 //             // do connection management: break connection 
    1372 // 
    1373 //             break; 
    1374 //         default: 
    1375 //             return 0; 
    1376 //         } 
    1377 //     } else { 
    1378         switch (i) { 
    1379         case 0: 
    1380             // do connection management: break connection 
    1381             iec61883_cmp_disconnect( 
    1382                 m_p1394Service->getHandle(), 
    1383                 m_pConfigRom->getNodeId() | 0xffc0, 
    1384                 plug, 
    1385                 raw1394_get_local_id (m_p1394Service->getHandle()), 
    1386                 hostplug, 
    1387                 m_receiveProcessor->getChannel(), 
    1388                 m_receiveProcessorBandwidth); 
    1389  
    1390             break; 
    1391         case 1: 
    1392             // do connection management: break connection 
    1393             iec61883_cmp_disconnect( 
    1394                 m_p1394Service->getHandle(), 
    1395                 raw1394_get_local_id (m_p1394Service->getHandle()), 
    1396                 hostplug, 
    1397                 m_pConfigRom->getNodeId() | 0xffc0, 
    1398                 plug, 
    1399                 m_transmitProcessor->getChannel(), 
    1400                 m_transmitProcessorBandwidth); 
    1401  
    1402             break; 
     1226             
    14031227        default: 
    14041228            return 0; 
  • branches/streaming-rework/src/devicemanager.cpp

    r407 r408  
    299299DeviceManager::getSyncSource() { 
    300300    IAvDevice* device = getAvDeviceByIndex(0); 
     301    return device->getStreamProcessorByIndex(0); 
    301302     
    302303    #warning TEST CODE FOR BOUNCE DEVICE !! 
  • branches/streaming-rework/src/libfreebobavc/ieee1394service.cpp

    r407 r408  
    2121 
    2222#include <libavc1394/avc1394.h> 
     23#include <libraw1394/csr.h> 
     24#include <libiec61883/iec61883.h> 
    2325 
    2426#include <errno.h> 
     
    3840{ 
    3941    pthread_mutex_init( &m_mutex, 0 ); 
     42     
     43    for (unsigned int i=0; i<64; i++) { 
     44        m_channels[i].channel=-1; 
     45        m_channels[i].bandwidth=-1; 
     46        m_channels[i].alloctype=AllocFree; 
     47        m_channels[i].xmit_node=0xFFFF; 
     48        m_channels[i].xmit_plug=-1; 
     49        m_channels[i].recv_node=0xFFFF; 
     50        m_channels[i].recv_plug=-1; 
     51    } 
    4052} 
    4153 
     
    349361    return false; 
    350362} 
     363 
     364/** 
     365 * Allocates an iso channel for use by the interface in a similar way to 
     366 * libiec61883.  Returns -1 on error (due to there being no free channels) 
     367 * or an allocated channel number. 
     368 * 
     369 * Does not perform anything other than registering the channel and the  
     370 * bandwidth at the IRM 
     371 * 
     372 * Also allocates the necessary bandwidth (in ISO allocation units). 
     373 *  
     374 * FIXME: As in libiec61883, channel 63 is not requested; this is either a 
     375 * bug or it's omitted since that's the channel preferred by video devices. 
     376 * 
     377 * @param bandwidth the bandwidth to allocate for this channel 
     378 * @return the channel number 
     379 */ 
     380signed int Ieee1394Service::allocateIsoChannelGeneric(unsigned int bandwidth) { 
     381    struct ChannelInfo cinfo; 
     382 
     383    int c = -1; 
     384    for (c = 0; c < 63; c++) { 
     385        if (raw1394_channel_modify (m_handle, c, RAW1394_MODIFY_ALLOC) == 0) 
     386            break; 
     387    } 
     388    if (c < 63) { 
     389        if (raw1394_bandwidth_modify(m_handle, bandwidth, RAW1394_MODIFY_ALLOC) < 0) { 
     390            debugFatal("Could not allocate bandwidth of %d\n", bandwidth); 
     391             
     392            raw1394_channel_modify (m_handle, c, RAW1394_MODIFY_FREE); 
     393            return -1; 
     394        } else { 
     395            cinfo.channel=c; 
     396            cinfo.bandwidth=bandwidth; 
     397            cinfo.alloctype=AllocGeneric; 
     398             
     399            if (registerIsoChannel(c, cinfo)) { 
     400                return c; 
     401            } else { 
     402                raw1394_bandwidth_modify(m_handle, bandwidth, RAW1394_MODIFY_FREE); 
     403                raw1394_channel_modify (m_handle, c, RAW1394_MODIFY_FREE); 
     404                return -1; 
     405            } 
     406        } 
     407    } 
     408    return -1; 
     409} 
     410 
     411/** 
     412 * Allocates an iso channel for use by the interface in a similar way to 
     413 * libiec61883.  Returns -1 on error (due to there being no free channels) 
     414 * or an allocated channel number. 
     415 * 
     416 * Uses IEC61883 Connection Management Procedure to establish the connection. 
     417 * 
     418 * Also allocates the necessary bandwidth (in ISO allocation units). 
     419 * 
     420 * @param xmit_node  node id of the transmitter 
     421 * @param xmit_plug  the output plug to use. If -1, find the first online plug, and 
     422 * upon return, contains the plug number used. 
     423 * @param recv_node  node id of the receiver 
     424 * @param recv_plug the input plug to use. If -1, find the first online plug, and 
     425 * upon return, contains the plug number used. 
     426 * 
     427 * @return the channel number 
     428 */ 
     429 
     430signed int Ieee1394Service::allocateIsoChannelCMP( 
     431    nodeid_t xmit_node, int xmit_plug,  
     432    nodeid_t recv_node, int recv_plug 
     433    ) { 
     434 
     435    struct ChannelInfo cinfo; 
     436     
     437    int c = -1; 
     438    int bandwidth=1; 
     439     
     440    // do connection management: make connection 
     441    c = iec61883_cmp_connect( 
     442        m_handle, 
     443        xmit_node | 0xffc0, 
     444        &xmit_plug, 
     445        recv_node | 0xffc0, 
     446        &recv_plug, 
     447        &bandwidth); 
     448 
     449    if((c<0) || (c>63)) { 
     450        debugError("Could not do CMP from %04X:%02d to %04X:%02d\n", 
     451            xmit_node, xmit_plug, recv_node, recv_plug 
     452            ); 
     453        return -1; 
     454    } 
     455 
     456    cinfo.channel=c; 
     457    cinfo.bandwidth=bandwidth; 
     458    cinfo.alloctype=AllocCMP; 
     459     
     460    cinfo.xmit_node=xmit_node; 
     461    cinfo.xmit_plug=xmit_plug; 
     462    cinfo.recv_node=recv_node; 
     463    cinfo.recv_plug=recv_plug; 
     464         
     465    if (registerIsoChannel(c, cinfo)) { 
     466        return c; 
     467    } 
     468 
     469    return -1; 
     470} 
     471 
     472/** 
     473 * Deallocates an iso channel.  Silently ignores a request to deallocate  
     474 * a negative channel number. 
     475 * 
     476 * Figures out the method that was used to allocate the channel (generic, cmp, ...) 
     477 * and uses the appropriate method to deallocate. Also frees the bandwidth 
     478 * that was reserved along with this channel. 
     479 *  
     480 * @param c channel number 
     481 * @return true if successful 
     482 */ 
     483bool Ieee1394Service::freeIsoChannel(signed int c) { 
     484     
     485    if (c < 0 || c > 63) { 
     486        debugWarning("Invalid channel number: %d", c); 
     487        return false; 
     488    } 
     489     
     490    switch (m_channels[c].alloctype) { 
     491        default: 
     492            debugError("BUG: invalid allocation type!\n"); 
     493            return false; 
     494             
     495        case AllocFree:  
     496            debugWarning("Channel %d not registered\n", c); 
     497            return false; 
     498             
     499        case AllocGeneric: 
     500            if (unregisterIsoChannel(c)) { 
     501                return false; 
     502            } else { 
     503                if (raw1394_bandwidth_modify(m_handle, m_channels[c].bandwidth, RAW1394_MODIFY_FREE) !=0) { 
     504                    debugWarning("Failed to deallocate bandwidth\n"); 
     505                } 
     506                if (raw1394_channel_modify (m_handle, m_channels[c].channel, RAW1394_MODIFY_FREE) != 0) { 
     507                    debugWarning("Failed to free channel\n"); 
     508                } 
     509                return true; 
     510            } 
     511             
     512        case AllocCMP: 
     513            if (unregisterIsoChannel(c)) { 
     514                return false; 
     515            } else { 
     516                if(iec61883_cmp_disconnect( 
     517                        m_handle,  
     518                        m_channels[c].xmit_node | 0xffc0, 
     519                        m_channels[c].xmit_plug, 
     520                        m_channels[c].recv_node | 0xffc0, 
     521                        m_channels[c].recv_plug, 
     522                        m_channels[c].channel, 
     523                        m_channels[c].bandwidth) != 0) { 
     524                    debugWarning("Could not do CMP disconnect for channel %d!\n",c); 
     525                } 
     526            } 
     527            return true; 
     528    } 
     529     
     530    // unreachable 
     531    debugError("BUG: unreachable code reached!\n"); 
     532     
     533    return false; 
     534} 
     535 
     536/** 
     537 * Registers a channel as managed by this ieee1394service 
     538 * @param c channel number 
     539 * @param cinfo channel info struct 
     540 * @return true if successful 
     541 */ 
     542bool Ieee1394Service::registerIsoChannel(unsigned int c, struct ChannelInfo cinfo) { 
     543    if (c < 63) { 
     544        if (m_channels[c].alloctype != AllocFree) { 
     545            debugWarning("Channel %d already registered with bandwidth %d\n", 
     546                m_channels[c].channel, m_channels[c].bandwidth); 
     547        } 
     548         
     549        memcpy(&m_channels[c], &cinfo, sizeof(struct ChannelInfo)); 
     550         
     551    } else return false; 
     552    return true; 
     553} 
     554 
     555/** 
     556 * unegisters a channel from this ieee1394service 
     557 * @param c channel number 
     558 * @return true if successful 
     559 */ 
     560bool Ieee1394Service::unregisterIsoChannel(unsigned int c) { 
     561    if (c < 63) { 
     562        if (m_channels[c].alloctype == AllocFree) { 
     563            debugWarning("Channel %d not registered\n", c); 
     564            return false; 
     565        } 
     566         
     567        m_channels[c].channel=-1; 
     568        m_channels[c].bandwidth=-1; 
     569        m_channels[c].alloctype=AllocFree; 
     570        m_channels[c].xmit_node=0xFFFF; 
     571        m_channels[c].xmit_plug=-1; 
     572        m_channels[c].recv_node=0xFFFF; 
     573        m_channels[c].recv_plug=-1; 
     574         
     575    } else return false; 
     576    return true; 
     577} 
     578 
     579/** 
     580 * Returns the current value of the `bandwidth available' register on 
     581 * the IRM, or -1 on error. 
     582 * @return  
     583 */ 
     584signed int Ieee1394Service::getAvailableBandwidth() { 
     585    quadlet_t buffer; 
     586    signed int result = raw1394_read (m_handle, raw1394_get_irm_id (m_handle), 
     587        CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, 
     588        sizeof (quadlet_t), &buffer); 
     589 
     590    if (result < 0) 
     591        return -1; 
     592    return ntohl(buffer); 
     593} 
  • branches/streaming-rework/src/libfreebobavc/ieee1394service.h

    r407 r408  
    126126    bool remBusResetHandler( Functor* functor ); 
    127127 
     128// ISO channel stuff 
     129public: 
     130    signed int getAvailableBandwidth(); 
     131    signed int allocateIsoChannelGeneric(unsigned int bandwidth); 
     132    signed int allocateIsoChannelCMP(nodeid_t xmit_node, int xmit_plug,  
     133                                     nodeid_t recv_node, int recv_plug); 
     134    bool freeIsoChannel(signed int channel); 
     135     
     136private: 
     137    enum EAllocType { 
     138        AllocFree = 0, // not allocated (by us) 
     139        AllocGeneric = 1, // allocated with generic functions 
     140        AllocCMP=2 // allocated with CMP 
     141    }; 
     142 
     143    struct ChannelInfo { 
     144        int channel; 
     145        int bandwidth; 
     146        enum EAllocType alloctype; 
     147        nodeid_t xmit_node; 
     148        int xmit_plug; 
     149        nodeid_t recv_node; 
     150        int recv_plug; 
     151    }; 
     152     
     153    // the info for the channels we manage 
     154    struct ChannelInfo m_channels[64]; 
     155     
     156    bool unregisterIsoChannel(unsigned int c); 
     157    bool registerIsoChannel(unsigned int c, struct ChannelInfo cinfo); 
     158 
    128159private: 
    129160 
  • branches/streaming-rework/src/motu/motu_avdevice.cpp

    r407 r408  
    5151}; 
    5252 
    53 /* ======================================================================= */ 
    54 /* Provide a mechanism for allocating iso channels and bandwidth to MOTU  
    55  * interfaces. 
    56  */ 
    57  
    58 static signed int allocate_iso_channel(raw1394handle_t handle) { 
    59 /* 
    60  * Allocates an iso channel for use by the interface in a similar way to 
    61  * libiec61883.  Returns -1 on error (due to there being no free channels) 
    62  * or an allocated channel number. 
    63  * FIXME: As in libiec61883, channel 63 is not requested; this is either a 
    64  * bug or it's omitted since that's the channel preferred by video devices. 
    65  */ 
    66         int c = -1; 
    67         for (c = 0; c < 63; c++) 
    68                 if (raw1394_channel_modify (handle, c, RAW1394_MODIFY_ALLOC) == 0) 
    69                         break; 
    70         if (c < 63) 
    71                 return c; 
    72         return -1; 
    73 } 
    74  
    75 static signed int free_iso_channel(raw1394handle_t handle, signed int channel) { 
    76 /* 
    77  * Deallocates an iso channel.  Returns -1 on error or 0 on success.  Silently 
    78  * ignores a request to deallocate a negative channel number. 
    79  */ 
    80         if (channel < 0) 
    81                 return 0; 
    82         if (raw1394_channel_modify (handle, channel, RAW1394_MODIFY_FREE)!=0) 
    83                 return -1; 
    84         return 0; 
    85 } 
    86  
    87 static signed int get_iso_bandwidth_avail(raw1394handle_t handle) { 
    88 /* 
    89  * Returns the current value of the `bandwidth available' register on 
    90  * the IRM, or -1 on error. 
    91  */ 
    92 quadlet_t buffer; 
    93 signed int result = raw1394_read (handle, raw1394_get_irm_id (handle), 
    94         CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, 
    95         sizeof (quadlet_t), &buffer); 
    96  
    97         if (result < 0) 
    98                 return -1; 
    99         return ntohl(buffer); 
    100 } 
    101 /* ======================================================================= */ 
    102  
    10353MotuDevice::MotuDevice( std::auto_ptr< ConfigRom >( configRom ), 
    10454                    Ieee1394Service& ieee1394service, 
     
    12777MotuDevice::~MotuDevice() 
    12878{ 
    129         // Free ieee1394 bus resources if they have been allocated 
    130         if (m_1394Service != NULL) { 
    131                 raw1394handle_t handle = m_1394Service->getHandle(); 
    132                 if (m_bandwidth >= 0) 
    133                         if (raw1394_bandwidth_modify(handle, m_bandwidth, RAW1394_MODIFY_FREE) < 0) 
    134                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free bandwidth of %d\n", m_bandwidth); 
    135                 if (m_iso_recv_channel >= 0) 
    136                         if (raw1394_channel_modify(handle, m_iso_recv_channel, RAW1394_MODIFY_FREE) < 0) 
    137                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free recv iso channel %d\n", m_iso_recv_channel); 
    138                 if (m_iso_send_channel >= 0) 
    139                         if (raw1394_channel_modify(handle, m_iso_send_channel, RAW1394_MODIFY_FREE) < 0) 
    140                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free send iso channel %d\n", m_iso_send_channel); 
    141         } 
     79    // Free ieee1394 bus resources if they have been allocated 
     80    if (m_1394Service != NULL) { 
     81        if(m_1394Service->freeIsoChannel(m_iso_recv_channel)) { 
     82            debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free recv iso channel %d\n", m_iso_recv_channel); 
     83             
     84        } 
     85        if(m_1394Service->freeIsoChannel(m_iso_send_channel)) { 
     86            debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free send iso channel %d\n", m_iso_send_channel); 
     87             
     88        } 
     89    } 
    14290} 
    14391 
     
    377325        unsigned int event_size_out= getEventSize(MOTUFW_DIR_OUT); 
    378326 
    379         raw1394handle_t handle = m_1394Service->getHandle(); 
    380  
    381327        debugOutput(DEBUG_LEVEL_NORMAL, "Preparing MotuDevice...\n" ); 
    382  
    383         // Assign iso channels if not already done 
    384         if (m_iso_recv_channel < 0) 
    385                 m_iso_recv_channel = allocate_iso_channel(handle); 
    386         if (m_iso_send_channel < 0) 
    387                 m_iso_send_channel = allocate_iso_channel(handle); 
    388  
    389         debugOutput(DEBUG_LEVEL_VERBOSE, "recv channel = %d, send channel = %d\n", 
    390                 m_iso_recv_channel, m_iso_send_channel); 
    391  
    392         if (m_iso_recv_channel<0 || m_iso_send_channel<0) { 
    393                 debugFatal("Could not allocate iso channels!\n"); 
    394                 return false; 
    395         } 
    396328 
    397329        // Allocate bandwidth if not previously done. 
     
    414346        // changed dynamically if this ends up being useful in future. 
    415347        m_bandwidth = 25 + 1160; 
    416         debugOutput(DEBUG_LEVEL_VERBOSE, "Available bandwidth: %d\n",  
    417                 get_iso_bandwidth_avail(handle)); 
    418         if (raw1394_bandwidth_modify(handle, m_bandwidth, RAW1394_MODIFY_ALLOC) < 0) { 
    419                 debugFatal("Could not allocate bandwidth of %d\n", m_bandwidth); 
    420                 m_bandwidth = -1; 
     348 
     349    // FIXME: bandwidth equally split over the channels 
     350 
     351        // Assign iso channels if not already done 
     352        if (m_iso_recv_channel < 0) 
     353                m_iso_recv_channel = m_1394Service->allocateIsoChannelGeneric(m_bandwidth/2); 
     354                 
     355        if (m_iso_send_channel < 0) 
     356                m_iso_send_channel = m_1394Service->allocateIsoChannelGeneric(m_bandwidth/2); 
     357 
     358        debugOutput(DEBUG_LEVEL_VERBOSE, "recv channel = %d, send channel = %d\n", 
     359                m_iso_recv_channel, m_iso_send_channel); 
     360 
     361        if (m_iso_recv_channel<0 || m_iso_send_channel<0) { 
     362                // be nice and deallocate 
     363                if (m_iso_recv_channel >= 0) 
     364                        m_1394Service->freeIsoChannel(m_iso_recv_channel); 
     365                if (m_iso_send_channel >= 0) 
     366                        m_1394Service->freeIsoChannel(m_iso_send_channel); 
     367                 
     368                debugFatal("Could not allocate iso channels!\n"); 
    421369                return false; 
    422370        } 
    423         debugOutput(DEBUG_LEVEL_VERBOSE,  
    424                 "allocated bandwidth of %d for MOTU device\n", m_bandwidth); 
    425         debugOutput(DEBUG_LEVEL_VERBOSE, 
    426                 "remaining bandwidth: %d\n", get_iso_bandwidth_avail(handle)); 
    427371 
    428372        m_receiveProcessor=new FreebobStreaming::MotuReceiveStreamProcessor( 
  • branches/streaming-rework/src/rme/rme_avdevice.cpp

    r407 r408  
    5151}; 
    5252 
    53 /* ======================================================================= */ 
    54 /* Provide a mechanism for allocating iso channels and bandwidth to MOTU  
    55  * interfaces. 
    56  */ 
    57  
    58 // static signed int allocate_iso_channel(raw1394handle_t handle) { 
    59 // /* 
    60 //  * Allocates an iso channel for use by the interface in a similar way to 
    61 //  * libiec61883.  Returns -1 on error (due to there being no free channels) 
    62 //  * or an allocated channel number. 
    63 //  * FIXME: As in libiec61883, channel 63 is not requested; this is either a 
    64 //  * bug or it's omitted since that's the channel preferred by video devices. 
    65 //  */ 
    66 //      int c = -1; 
    67 //      for (c = 0; c < 63; c++) 
    68 //              if (raw1394_channel_modify (handle, c, RAW1394_MODIFY_ALLOC) == 0) 
    69 //                      break; 
    70 //      if (c < 63) 
    71 //              return c; 
    72 //      return -1; 
    73 // } 
    74  
    75 // static signed int free_iso_channel(raw1394handle_t handle, signed int channel) { 
    76 // /* 
    77 //  * Deallocates an iso channel.  Returns -1 on error or 0 on success.  Silently 
    78 //  * ignores a request to deallocate a negative channel number. 
    79 //  */ 
    80 //      if (channel < 0) 
    81 //              return 0; 
    82 //      if (raw1394_channel_modify (handle, channel, RAW1394_MODIFY_FREE)!=0) 
    83 //              return -1; 
    84 //      return 0; 
    85 // } 
    86  
    87 // static signed int get_iso_bandwidth_avail(raw1394handle_t handle) { 
    88 // /* 
    89 //  * Returns the current value of the `bandwidth available' register on 
    90 //  * the IRM, or -1 on error. 
    91 //  */ 
    92 // quadlet_t buffer; 
    93 // signed int result = raw1394_read (handle, raw1394_get_irm_id (handle), 
    94 //      CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, 
    95 //      sizeof (quadlet_t), &buffer); 
    96 //  
    97 //      if (result < 0) 
    98 //              return -1; 
    99 //      return ntohl(buffer); 
    100 // } 
    101 /* ======================================================================= */ 
    102  
    10353RmeDevice::RmeDevice( std::auto_ptr< ConfigRom >( configRom ), 
    10454                    Ieee1394Service& ieee1394service, 
     
    12777RmeDevice::~RmeDevice() 
    12878{ 
    129         // Free ieee1394 bus resources if they have been allocated 
    130         if (m_1394Service != NULL) { 
    131                 raw1394handle_t handle = m_1394Service->getHandle(); 
    132                 if (m_bandwidth >= 0) 
    133                         if (raw1394_bandwidth_modify(handle, m_bandwidth, RAW1394_MODIFY_FREE) < 0) 
    134                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free bandwidth of %d\n", m_bandwidth); 
    135                 if (m_iso_recv_channel >= 0) 
    136                         if (raw1394_channel_modify(handle, m_iso_recv_channel, RAW1394_MODIFY_FREE) < 0) 
    137                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free recv iso channel %d\n", m_iso_recv_channel); 
    138                 if (m_iso_send_channel >= 0) 
    139                         if (raw1394_channel_modify(handle, m_iso_send_channel, RAW1394_MODIFY_FREE) < 0) 
    140                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free send iso channel %d\n", m_iso_send_channel); 
    141         } 
    142  
     79    // Free ieee1394 bus resources if they have been allocated 
     80    if (m_1394Service != NULL) { 
     81        if(m_1394Service->freeIsoChannel(m_iso_recv_channel)) { 
     82            debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free recv iso channel %d\n", m_iso_recv_channel); 
     83             
     84        } 
     85        if(m_1394Service->freeIsoChannel(m_iso_send_channel)) { 
     86            debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free send iso channel %d\n", m_iso_send_channel); 
     87             
     88        } 
     89    } 
    14390} 
    14491 
     
    233180RmeDevice::prepare() { 
    234181 
    235 //      int samp_freq = getSamplingFrequency(); 
    236  
    237 //      raw1394handle_t handle = m_1394Service->getHandle(); 
    238  
    239         debugOutput(DEBUG_LEVEL_NORMAL, "Preparing MotuDevice...\n" ); 
    240  
    241         // Assign iso channels if not already done 
    242 //      if (m_iso_recv_channel < 0) 
    243 //              m_iso_recv_channel = allocate_iso_channel(handle); 
    244 //      if (m_iso_send_channel < 0) 
    245 //              m_iso_send_channel = allocate_iso_channel(handle); 
    246 // 
    247 //      debugOutput(DEBUG_LEVEL_VERBOSE, "recv channel = %d, send channel = %d\n", 
    248 //              m_iso_recv_channel, m_iso_send_channel); 
    249 // 
    250 //      if (m_iso_recv_channel<0 || m_iso_send_channel<0) { 
    251 //              debugFatal("Could not allocate iso channels!\n"); 
    252 //              return false; 
    253 //      } 
    254  
    255         // Allocate bandwidth if not previously done. 
    256         // FIXME: The bandwidth allocation calculation can probably be 
    257         // refined somewhat since this is currently based on a rudimentary 
    258         // understanding of the iso protocol. 
    259         // Currently we assume the following. 
    260         //   * Ack/iso gap = 0.05 us 
    261         //   * DATA_PREFIX = 0.16 us 
    262         //   * DATA_END    = 0.26 us 
    263         // These numbers are the worst-case figures given in the ieee1394 
    264         // standard.  This gives approximately 0.5 us of overheads per 
    265         // packet - around 25 bandwidth allocation units (from the ieee1394 
    266         // standard 1 bandwidth allocation unit is 125/6144 us).  We further 
    267         // assume the MOTU is running at S400 (which it should be) so one 
    268         // allocation unit is equivalent to 1 transmitted byte; thus the 
    269         // bandwidth allocation required for the packets themselves is just 
    270         // the size of the packet.  We allocate based on the maximum packet 
    271         // size (1160 bytes at 192 kHz) so the sampling frequency can be 
    272         // changed dynamically if this ends up being useful in future. 
    273 //      m_bandwidth = 25 + 1160; 
    274 //      debugOutput(DEBUG_LEVEL_VERBOSE, "Available bandwidth: %d\n",  
    275 //              get_iso_bandwidth_avail(handle)); 
    276 //      if (raw1394_bandwidth_modify(handle, m_bandwidth, RAW1394_MODIFY_ALLOC) < 0) { 
    277 //              debugFatal("Could not allocate bandwidth of %d\n", m_bandwidth); 
    278 //              m_bandwidth = -1; 
    279 //              return false; 
    280 //      } 
    281 //      debugOutput(DEBUG_LEVEL_VERBOSE,  
    282 //              "allocated bandwidth of %d for MOTU device\n", m_bandwidth); 
    283 //      debugOutput(DEBUG_LEVEL_VERBOSE, 
    284 //              "remaining bandwidth: %d\n", get_iso_bandwidth_avail(handle)); 
    285  
    286 //      m_receiveProcessor=new FreebobStreaming::MotuReceiveStreamProcessor( 
    287 //              m_1394Service->getPort(), samp_freq, event_size_in); 
    288  
    289         // The first thing is to initialize the processor.  This creates the 
    290         // data structures. 
    291 //      if(!m_receiveProcessor->init()) { 
    292 //              debugFatal("Could not initialize receive processor!\n"); 
    293 //              return false; 
    294 //      } 
    295 //      m_receiveProcessor->setVerboseLevel(getDebugLevel()); 
    296  
    297         // Now we add ports to the processor 
    298 //      debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to receive processor\n"); 
    299          
    300 //      char *buff; 
    301 //      FreebobStreaming::Port *p=NULL; 
    302 // 
    303 //      // Add audio capture ports 
    304 //      if (!addDirPorts(FreebobStreaming::Port::E_Capture, samp_freq, optical_in_mode)) { 
    305 //              return false; 
    306 //      } 
    307  
    308         // Add MIDI port.  The MOTU only has one MIDI input port, with each 
    309         // MIDI byte sent using a 3 byte sequence starting at byte 4 of the 
    310         // event data. 
    311 //      asprintf(&buff,"dev%d_cap_MIDI0",m_id); 
    312 //      p = new FreebobStreaming::MotuMidiPort(buff, 
    313 //              FreebobStreaming::Port::E_Capture, 4); 
    314 //      if (!p) { 
    315 //              debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 
    316 //      } else { 
    317 //              if (!m_receiveProcessor->addPort(p)) { 
    318 //                      debugWarning("Could not register port with stream processor\n"); 
    319 //                      free(buff); 
    320 //                      return false; 
    321 //              } else { 
    322 //                      debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff); 
    323 //              } 
    324 //      } 
    325 //      free(buff); 
    326  
    327         // example of adding an control port: 
    328 //    asprintf(&buff,"dev%d_cap_%s",m_id,"myportnamehere"); 
    329 //    p=new FreebobStreaming::MotuControlPort( 
    330 //            buff, 
    331 //            FreebobStreaming::Port::E_Capture,  
    332 //            0 // you can add all other port specific stuff you  
    333 //              // need to pass by extending MotuXXXPort and MotuPortInfo 
    334 //    ); 
    335 //    free(buff); 
    336 // 
    337 //    if (!p) { 
    338 //        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff); 
    339 //    } else { 
    340 // 
    341 //        if (!m_receiveProcessor->addPort(p)) { 
    342 //            debugWarning("Could not register port with stream processor\n"); 
    343 //            return false; 
    344 //        } else { 
    345 //            debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff); 
    346 //        } 
    347 //    } 
    348  
    349         // Do the same for the transmit processor 
    350 //      m_transmitProcessor=new FreebobStreaming::MotuTransmitStreamProcessor( 
    351 //              m_1394Service->getPort(), getSamplingFrequency(), event_size_out); 
    352 // 
    353 //      m_transmitProcessor->setVerboseLevel(getDebugLevel()); 
    354 //       
    355 //      if(!m_transmitProcessor->init()) { 
    356 //              debugFatal("Could not initialize transmit processor!\n"); 
    357 //              return false; 
    358 //      } 
    359  
    360         // Connect the transmit stream ticks-per-frame hook to the 
    361         // ticks-per-frame DLL integrator in the receive stream. 
    362 //      m_transmitProcessor->setTicksPerFrameDLL(m_receiveProcessor->getTicksPerFrameDLL()); 
    363  
    364         // Now we add ports to the processor 
    365 //      debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to transmit processor\n"); 
    366  
    367         // Add audio playback ports 
    368 //      if (!addDirPorts(FreebobStreaming::Port::E_Playback, samp_freq, optical_out_mode)) { 
    369 //              return false; 
    370 //      } 
    371  
    372         // Add MIDI port.  The MOTU only has one output MIDI port, with each 
    373         // MIDI byte transmitted using a 3 byte sequence starting at byte 4 
    374         // of the event data. 
    375 //      asprintf(&buff,"dev%d_pbk_MIDI0",m_id); 
    376 //      p = new FreebobStreaming::MotuMidiPort(buff, 
    377 //              FreebobStreaming::Port::E_Capture, 4); 
    378 //      if (!p) { 
    379 //              debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 
    380 //      } else { 
    381 //              if (!m_receiveProcessor->addPort(p)) { 
    382 //                      debugWarning("Could not register port with stream processor\n"); 
    383 //                      free(buff); 
    384 //                      return false; 
    385 //              } else { 
    386 //                      debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff); 
    387 //              } 
    388 //      } 
    389 //      free(buff); 
    390  
    391         // example of adding an control port: 
    392 //    asprintf(&buff,"dev%d_pbk_%s",m_id,"myportnamehere"); 
    393 //     
    394 //    p=new FreebobStreaming::MotuControlPort( 
    395 //            buff, 
    396 //            FreebobStreaming::Port::E_Playback,  
    397 //            0 // you can add all other port specific stuff you  
    398 //              // need to pass by extending MotuXXXPort and MotuPortInfo 
    399 //    ); 
    400 //    free(buff); 
    401 // 
    402 //    if (!p) { 
    403 //        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff); 
    404 //    } else { 
    405 //        if (!m_transmitProcessor->addPort(p)) { 
    406 //            debugWarning("Could not register port with stream processor\n"); 
    407 //            return false; 
    408 //        } else { 
    409 //            debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff); 
    410 //        } 
    411 //    } 
    412          
     182        debugOutput(DEBUG_LEVEL_NORMAL, "Preparing RmeDevice...\n" ); 
     183 
    413184        return true; 
    414185} 
     
    416187int  
    417188RmeDevice::getStreamCount() { 
    418         return 2; // one receive, one transmit 
     189        return 0; // one receive, one transmit 
    419190} 
    420191 
    421192FreebobStreaming::StreamProcessor * 
    422193RmeDevice::getStreamProcessorByIndex(int i) { 
    423  
    424 //      switch (i) { 
    425 //      case 0: 
    426 //              return m_receiveProcessor; 
    427 //      case 1: 
    428 //              return m_transmitProcessor; 
    429 //      default: 
    430 //              return NULL; 
    431 //      } 
    432 //      return 0; 
    433         return NULL; 
     194    return NULL; 
    434195} 
    435196 
    436197int 
    437198RmeDevice::startStreamByIndex(int i) { 
    438  
    439         // NOTE: this assumes that you have two streams 
    440         switch (i) { 
    441         case 0: 
    442                 // TODO: do the stuff that is nescessary to make the device 
    443                 // transmit a stream 
    444  
    445                 // Set the streamprocessor channel to the one obtained by  
    446                 // the connection management 
    447 //              m_receiveProcessor->setChannel(m_iso_recv_channel); 
    448  
    449                 // Mask out current transmit settings of the MOTU and replace 
    450                 // with new ones.  Turn bit 24 on to enable changes to the 
    451                 // MOTU's iso transmit settings when the iso control register 
    452                 // is written.  Bit 23 enables iso transmit from the MOTU. 
    453                 break; 
    454         case 1: 
    455                 // TODO: do the stuff that is nescessary to make the device 
    456                 // receive a stream 
    457  
    458                 // Set the streamprocessor channel to the one obtained by  
    459                 // the connection management 
    460 //              m_transmitProcessor->setChannel(m_iso_send_channel); 
    461  
    462                 // Mask out current receive settings of the MOTU and replace 
    463                 // with new ones.  Turn bit 31 on to enable changes to the 
    464                 // MOTU's iso receive settings when the iso control register 
    465                 // is written.  Bit 30 enables iso receive by the MOTU. 
    466                 break; 
    467                  
    468         default: // Invalid stream index 
    469                 return -1; 
    470         } 
    471  
    472         return 0; 
     199    return -1; 
    473200} 
    474201 
    475202int 
    476203RmeDevice::stopStreamByIndex(int i) { 
    477  
    478         // TODO: connection management: break connection 
    479         // cfr the start function 
    480  
    481         // NOTE: this assumes that you have two streams 
    482         switch (i) { 
    483         case 0: 
    484                 break; 
    485         case 1: 
    486                 break; 
    487                  
    488         default: // Invalid stream index 
    489                 return -1; 
    490         } 
    491  
    492         return 0; 
     204    return -1; 
     205 
    493206} 
    494207 
     
    502215 
    503216signed int RmeDevice::getEventSize(unsigned int dir) { 
    504 // 
    505 // Return the size in bytes of a single event sent to (dir==MOTUFW_OUT) or 
    506 // from (dir==MOTUFW_IN) the MOTU as part of an iso data packet. 
    507  
    508         return 1; 
    509 
    510 /* ======================================================================= */ 
    511  
    512 #if 0 
    513 unsigned int RmeDevice::ReadRegister(unsigned int reg) { 
    514 /* 
    515  * Attempts to read the requested register from the RME device. 
    516  */ 
    517  
    518 quadlet_t quadlet; 
    519 assert(m_1394Service); 
    520          
    521   quadlet = 0; 
    522   // Note: 1394Service::read() expects a physical ID, not the node id 
    523   if (m_1394Service->read(0xffc0 | m_nodeId, MOTUFW_BASE_ADDR+reg, 1, &quadlet) < 0) { 
    524     debugError("Error doing rme read from register 0x%06x\n",reg); 
    525   } 
    526  
    527   return ntohl(quadlet); 
    528 
    529  
    530 signed int RmeDevice::WriteRegister(unsigned int reg, quadlet_t data) { 
    531 /* 
    532  * Attempts to write the given data to the requested RME register. 
    533  */ 
    534  
    535   unsigned int err = 0; 
    536   data = htonl(data); 
    537  
    538   // Note: 1394Service::write() expects a physical ID, not the node id 
    539   if (m_1394Service->write(0xffc0 | m_nodeId, MOTUFW_BASE_ADDR+reg, 1, &data) < 0) { 
    540     err = 1; 
    541     debugError("Error doing rme write to register 0x%06x\n",reg); 
    542   } 
    543  
    544   usleep(100); 
    545   return (err==0)?0:-1; 
    546 
    547 #endif 
    548  
    549 
     217    return 0; 
     218
     219 
     220