Changeset 1765

Show
Ignore:
Timestamp:
12/23/09 11:10:49 (14 years ago)
Author:
ppalmers
Message:

put everything related to iso streaming into one CPP file. this should give the compiler some more freedom to optimize.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/genericavc/stanton/scs.cpp

    r1763 r1765  
    149149bool 
    150150ScsDevice::writeHSS1394Message(enum eMessageType message_type, byte_t* buffer, size_t len) { 
    151     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing message type: %02X, length: %zd bytes\n", 
    152         message_type, len); 
     151    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 
     152                "Writing message type: %02X, length: %zd bytes\n", 
     153                message_type, len); 
    153154    size_t len_quadlets = len/4 + 1; 
    154155 
  • trunk/libffado/src/libavc/general/avc_plug.cpp

    r1764 r1765  
    14261426            return string("Unknown"); 
    14271427    } 
     1428    return string("ERROR"); 
    14281429} 
    14291430 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r1763 r1765  
    3939 
    4040IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL ); 
    41 IMPL_DEBUG_MODULE( IsoTask, IsoTask, DEBUG_LEVEL_NORMAL ); 
     41IMPL_DEBUG_MODULE( IsoHandlerManager::IsoTask, IsoTask, DEBUG_LEVEL_NORMAL ); 
     42IMPL_DEBUG_MODULE( IsoHandlerManager::IsoHandler, IsoHandler, DEBUG_LEVEL_NORMAL ); 
    4243 
    4344using namespace Streaming; 
     
    4546// --- ISO Thread --- // 
    4647 
    47 IsoTask::IsoTask(IsoHandlerManager& manager, enum IsoHandler::EHandlerType t) 
     48IsoHandlerManager::IsoTask::IsoTask(IsoHandlerManager& manager, enum IsoHandler::EHandlerType t) 
    4849    : m_manager( manager ) 
    4950    , m_SyncIsoHandler ( NULL ) 
     
    5556} 
    5657 
    57 IsoTask::~IsoTask() 
     58IsoHandlerManager::IsoTask::~IsoTask() 
    5859{ 
    5960    sem_destroy(&m_activity_semaphore); 
     
    6162 
    6263bool 
    63 IsoTask::Init() 
     64IsoHandlerManager::IsoTask::Init() 
    6465{ 
    6566    request_update = 0; 
     
    8384 
    8485void 
    85 IsoTask::requestShadowMapUpdate() 
     86IsoHandlerManager::IsoTask::requestShadowMapUpdate() 
    8687{ 
    8788    debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) enter\n", this); 
     
    9495 
    9596bool 
    96 IsoTask::handleBusReset() 
     97IsoHandlerManager::IsoTask::handleBusReset() 
    9798{ 
    9899    bool retval = true; 
     
    129130// nobody will modify the parent data structures 
    130131void 
    131 IsoTask::updateShadowMapHelper() 
     132IsoHandlerManager::IsoTask::updateShadowMapHelper() 
    132133{ 
    133134    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) updating shadow vars...\n", this); 
     
    191192 
    192193bool 
    193 IsoTask::Execute() 
     194IsoHandlerManager::IsoTask::Execute() 
    194195{ 
    195196    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     
    266267            // wait for something to happen 
    267268            switch(waitForActivity()) { 
    268                 case IsoTask::eAR_Error: 
     269                case IsoHandlerManager::IsoTask::eAR_Error: 
    269270                    debugError("Error while waiting for activity\n"); 
    270271                    return false; 
    271                 case IsoTask::eAR_Interrupted: 
     272                case IsoHandlerManager::IsoTask::eAR_Interrupted: 
    272273                    // FIXME: what to do here? 
    273274                    debugWarning("Interrupted while waiting for activity\n"); 
    274275                    break; 
    275                 case IsoTask::eAR_Timeout: 
     276                case IsoHandlerManager::IsoTask::eAR_Timeout: 
    276277                    // FIXME: what to do here? 
    277278                    debugWarning("Timeout while waiting for activity\n"); 
    278279                    no_one_to_poll = false; // exit the loop to be able to detect failing handlers 
    279280                    break; 
    280                 case IsoTask::eAR_Activity: 
     281                case IsoHandlerManager::IsoTask::eAR_Activity: 
    281282                    // do nothing 
    282283                    debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
     
    374375} 
    375376 
    376 enum IsoTask::eActivityResult 
    377 IsoTask::waitForActivity() 
     377enum IsoHandlerManager::IsoTask::eActivityResult 
     378IsoHandlerManager::IsoTask::waitForActivity() 
    378379{ 
    379380    debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
     
    431432 
    432433void 
    433 IsoTask::signalActivity() 
     434IsoHandlerManager::IsoTask::signalActivity() 
    434435{ 
    435436    // signal the activity cond var 
     
    440441} 
    441442 
    442 void IsoTask::setVerboseLevel(int i) { 
     443void IsoHandlerManager::IsoTask::setVerboseLevel(int i) { 
    443444    setDebugLevel(i); 
    444445    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i ); 
     
    981982} 
    982983 
    983 IsoHandler
     984IsoHandlerManager::IsoHandler
    984985IsoHandlerManager::getHandlerForStream(Streaming::StreamProcessor *stream) { 
    985986    for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
     
    993994    debugError("Stream %p has no attached handler\n", stream); 
    994995    return NULL; 
     996} 
     997 
     998void 
     999IsoHandlerManager::dumpInfoForStream(Streaming::StreamProcessor *stream) 
     1000{ 
     1001    IsoHandler *h = getHandlerForStream(stream); 
     1002    if (h) { 
     1003        debugOutputShort( DEBUG_LEVEL_NORMAL, "  Packets, Dropped, Skipped : %d, %d, %d\n", 
     1004                            h->m_packets, h->m_dropped, h->m_skipped); 
     1005    } else { 
     1006        debugError("No handler for stream %p??\n", stream); 
     1007    } 
    9951008} 
    9961009 
     
    11571170    } 
    11581171} 
     1172 
     1173 
     1174// ISOHANDLER 
     1175 
     1176/* the C callbacks */ 
     1177enum raw1394_iso_disposition 
     1178IsoHandlerManager::IsoHandler::iso_transmit_handler(raw1394handle_t handle, 
     1179        unsigned char *data, unsigned int *length, 
     1180        unsigned char *tag, unsigned char *sy, 
     1181        int cycle, unsigned int dropped1) { 
     1182 
     1183    IsoHandler *xmitHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle)); 
     1184    assert(xmitHandler); 
     1185    unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16; 
     1186    unsigned int dropped = dropped1 & 0xFFFF; 
     1187    return xmitHandler->getPacket(data, length, tag, sy, cycle, dropped, skipped); 
     1188} 
     1189 
     1190enum raw1394_iso_disposition 
     1191IsoHandlerManager::IsoHandler::iso_receive_handler(raw1394handle_t handle, unsigned char *data, 
     1192                        unsigned int length, unsigned char channel, 
     1193                        unsigned char tag, unsigned char sy, unsigned int cycle, 
     1194                        unsigned int dropped) { 
     1195 
     1196    IsoHandler *recvHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle)); 
     1197    assert(recvHandler); 
     1198 
     1199    return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped); 
     1200} 
     1201 
     1202IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t) 
     1203   : m_manager( manager ) 
     1204   , m_type ( t ) 
     1205   , m_handle( NULL ) 
     1206   , m_buf_packets( 400 ) 
     1207   , m_max_packet_size( 1024 ) 
     1208   , m_irq_interval( -1 ) 
     1209   , m_last_cycle( -1 ) 
     1210   , m_last_now( 0xFFFFFFFF ) 
     1211   , m_last_packet_handled_at( 0xFFFFFFFF ) 
     1212   , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER ) 
     1213   , m_Client( 0 ) 
     1214   , m_speed( RAW1394_ISO_SPEED_400 ) 
     1215   , m_State( eHS_Stopped ) 
     1216   , m_NextState( eHS_Stopped ) 
     1217   , m_switch_on_cycle(0) 
     1218#ifdef DEBUG 
     1219   , m_packets ( 0 ) 
     1220   , m_dropped( 0 ) 
     1221   , m_skipped( 0 ) 
     1222   , m_min_ahead( 7999 ) 
     1223#endif 
     1224{ 
     1225} 
     1226 
     1227IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t,  
     1228                       unsigned int buf_packets, unsigned int max_packet_size, int irq) 
     1229   : m_manager( manager ) 
     1230   , m_type ( t ) 
     1231   , m_handle( NULL ) 
     1232   , m_buf_packets( buf_packets ) 
     1233   , m_max_packet_size( max_packet_size ) 
     1234   , m_irq_interval( irq ) 
     1235   , m_last_cycle( -1 ) 
     1236   , m_last_now( 0xFFFFFFFF ) 
     1237   , m_last_packet_handled_at( 0xFFFFFFFF ) 
     1238   , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER ) 
     1239   , m_Client( 0 ) 
     1240   , m_speed( RAW1394_ISO_SPEED_400 ) 
     1241   , m_State( eHS_Stopped ) 
     1242   , m_NextState( eHS_Stopped ) 
     1243   , m_switch_on_cycle(0) 
     1244#ifdef DEBUG 
     1245   , m_packets ( 0 ) 
     1246   , m_dropped( 0 ) 
     1247   , m_skipped( 0 ) 
     1248   , m_min_ahead( 7999 ) 
     1249#endif 
     1250{ 
     1251} 
     1252 
     1253IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t, unsigned int buf_packets, 
     1254                       unsigned int max_packet_size, int irq, 
     1255                       enum raw1394_iso_speed speed) 
     1256   : m_manager( manager ) 
     1257   , m_type ( t ) 
     1258   , m_handle( NULL ) 
     1259   , m_buf_packets( buf_packets ) 
     1260   , m_max_packet_size( max_packet_size ) 
     1261   , m_irq_interval( irq ) 
     1262   , m_last_cycle( -1 ) 
     1263   , m_last_now( 0xFFFFFFFF ) 
     1264   , m_last_packet_handled_at( 0xFFFFFFFF ) 
     1265   , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER ) 
     1266   , m_Client( 0 ) 
     1267   , m_speed( speed ) 
     1268   , m_State( eHS_Stopped ) 
     1269   , m_NextState( eHS_Stopped ) 
     1270   , m_switch_on_cycle(0) 
     1271#ifdef DEBUG 
     1272   , m_packets( 0 ) 
     1273   , m_dropped( 0 ) 
     1274   , m_skipped( 0 ) 
     1275   , m_min_ahead( 7999 ) 
     1276#endif 
     1277{ 
     1278} 
     1279 
     1280IsoHandlerManager::IsoHandler::~IsoHandler() { 
     1281// Don't call until libraw1394's raw1394_new_handle() function has been 
     1282// fixed to correctly initialise the iso_packet_infos field.  Bug is 
     1283// confirmed present in libraw1394 1.2.1.  In any case, 
     1284// raw1394_destroy_handle() will do any iso system shutdown required. 
     1285//     raw1394_iso_shutdown(m_handle); 
     1286    if(m_handle) { 
     1287        if (m_State == eHS_Running) { 
     1288            debugError("BUG: Handler still running!\n"); 
     1289            disable(); 
     1290        } 
     1291    } 
     1292} 
     1293 
     1294bool 
     1295IsoHandlerManager::IsoHandler::canIterateClient() 
     1296{ 
     1297    debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "checking...\n"); 
     1298    if(m_Client) { 
     1299        bool result; 
     1300 
     1301        if (m_type == eHT_Receive) { 
     1302            result = m_Client->canProducePacket(); 
     1303        } else { 
     1304            result = m_Client->canConsumePacket(); 
     1305        } 
     1306        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result); 
     1307        return result && (m_State != eHS_Error); 
     1308    } else { 
     1309        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " no client\n"); 
     1310    } 
     1311    return false; 
     1312} 
     1313 
     1314bool 
     1315IsoHandlerManager::IsoHandler::iterate() { 
     1316    return iterate(m_manager.get1394Service().getCycleTimer()); 
     1317} 
     1318 
     1319bool 
     1320IsoHandlerManager::IsoHandler::iterate(uint32_t cycle_timer_now) { 
     1321    debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) Iterating ISO handler at %08X...\n", 
     1322                       this, getTypeString(), cycle_timer_now); 
     1323    m_last_now = cycle_timer_now; 
     1324    if(m_State == eHS_Running) { 
     1325        assert(m_handle); 
     1326 
     1327        #if ISOHANDLER_FLUSH_BEFORE_ITERATE 
     1328        // this flushes all packets received since the poll() returned 
     1329        // from kernel to userspace such that they are processed by this 
     1330        // iterate. Doing so might result in lower latency capability 
     1331        // and/or better reliability 
     1332        if(m_type == eHT_Receive) { 
     1333            raw1394_iso_recv_flush(m_handle); 
     1334        } 
     1335        #endif 
     1336 
     1337        if(raw1394_loop_iterate(m_handle)) { 
     1338            debugError( "IsoHandler (%p): Failed to iterate handler: %s\n", 
     1339                        this, strerror(errno)); 
     1340            return false; 
     1341        } 
     1342        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) done interating ISO handler...\n", 
     1343                           this, getTypeString()); 
     1344        return true; 
     1345    } else { 
     1346        debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) Not iterating a non-running handler...\n", 
     1347                    this, getTypeString()); 
     1348        return false; 
     1349    } 
     1350} 
     1351 
     1352/** 
     1353 * Bus reset handler 
     1354 * 
     1355 * @return ? 
     1356 */ 
     1357 
     1358bool 
     1359IsoHandlerManager::IsoHandler::handleBusReset() 
     1360{ 
     1361    debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n"); 
     1362    m_last_packet_handled_at = 0xFFFFFFFF; 
     1363 
     1364    #define CSR_CYCLE_TIME            0x200 
     1365    #define CSR_REGISTER_BASE  0xfffff0000000ULL 
     1366    // do a simple read on ourself in order to update the internal structures 
     1367    // this avoids read failures after a bus reset 
     1368    quadlet_t buf=0; 
     1369    raw1394_read(m_handle, raw1394_get_local_id(m_handle), 
     1370                 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 
     1371 
     1372    return m_Client->handleBusReset(); 
     1373} 
     1374 
     1375/** 
     1376 * Call this if you find out that this handler has died for some 
     1377 * external reason. 
     1378 */ 
     1379void 
     1380IsoHandlerManager::IsoHandler::notifyOfDeath() 
     1381{ 
     1382    m_State = eHS_Error; 
     1383    m_NextState = eHS_Error; 
     1384 
     1385    // notify the client of the fact that we have died 
     1386    m_Client->handlerDied(); 
     1387 
     1388    // wake ourselves up 
     1389    if(m_handle) raw1394_wake_up(m_handle); 
     1390} 
     1391 
     1392void IsoHandlerManager::IsoHandler::dumpInfo() 
     1393{ 
     1394    int channel=-1; 
     1395    if (m_Client) channel=m_Client->getChannel(); 
     1396 
     1397    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Handler type................: %s\n", 
     1398            getTypeString()); 
     1399    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel...............: %2d, %2d\n", 
     1400            m_manager.get1394Service().getPort(), channel); 
     1401    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer, MaxPacketSize, IRQ..: %4d, %4d, %4d\n", 
     1402            m_buf_packets, m_max_packet_size, m_irq_interval); 
     1403    if (this->getType() == eHT_Transmit) { 
     1404        debugOutputShort( DEBUG_LEVEL_NORMAL, "  Speed ..................: %2d\n", 
     1405                                            m_speed); 
     1406        #ifdef DEBUG 
     1407        debugOutputShort( DEBUG_LEVEL_NORMAL, "  Min ISOXMT bufferfill : %04d\n", m_min_ahead); 
     1408        #endif 
     1409    } 
     1410    #ifdef DEBUG 
     1411    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Last cycle, dropped.........: %4d, %4u, %4u\n", 
     1412            m_last_cycle, m_dropped, m_skipped); 
     1413    #endif 
     1414 
     1415} 
     1416 
     1417void IsoHandlerManager::IsoHandler::setVerboseLevel(int l) 
     1418{ 
     1419    setDebugLevel(l); 
     1420    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 
     1421} 
     1422 
     1423bool IsoHandlerManager::IsoHandler::registerStream(StreamProcessor *stream) 
     1424{ 
     1425    assert(stream); 
     1426    debugOutput( DEBUG_LEVEL_VERBOSE, "registering stream (%p)\n", stream); 
     1427 
     1428    if (m_Client) { 
     1429            debugFatal( "Generic IsoHandlers can have only one client\n"); 
     1430            return false; 
     1431    } 
     1432    m_Client=stream; 
     1433    return true; 
     1434} 
     1435 
     1436bool IsoHandlerManager::IsoHandler::unregisterStream(StreamProcessor *stream) 
     1437{ 
     1438    assert(stream); 
     1439    debugOutput( DEBUG_LEVEL_VERBOSE, "unregistering stream (%p)\n", stream); 
     1440 
     1441    if(stream != m_Client) { 
     1442            debugFatal( "no client registered\n"); 
     1443            return false; 
     1444    } 
     1445    m_Client=0; 
     1446    return true; 
     1447} 
     1448 
     1449// ISO packet interface 
     1450enum raw1394_iso_disposition IsoHandlerManager::IsoHandler::putPacket( 
     1451                    unsigned char *data, unsigned int length, 
     1452                    unsigned char channel, unsigned char tag, unsigned char sy, 
     1453                    unsigned int cycle, unsigned int dropped) { 
     1454    // keep track of dropped cycles 
     1455    int dropped_cycles = 0; 
     1456    if (m_last_cycle != (int)cycle && m_last_cycle != -1) { 
     1457        dropped_cycles = diffCycles(cycle, m_last_cycle) - 1; 
     1458        #ifdef DEBUG 
     1459        if (dropped_cycles < 0) { 
     1460            debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d\n",  
     1461                         this, dropped_cycles, cycle, m_last_cycle, dropped); 
     1462        } 
     1463        if (dropped_cycles > 0) { 
     1464            debugOutput(DEBUG_LEVEL_VERBOSE, 
     1465                        "(%p) dropped %d packets on cycle %u, 'dropped'=%u, cycle=%d, m_last_cycle=%d\n", 
     1466                        this, dropped_cycles, cycle, dropped, cycle, m_last_cycle); 
     1467            m_dropped += dropped_cycles; 
     1468        } 
     1469        #endif 
     1470    } 
     1471    m_last_cycle = cycle; 
     1472 
     1473    // the m_last_now value is set when the iterate() function is called. 
     1474    uint32_t now_cycles = CYCLE_TIMER_GET_CYCLES(m_last_now); 
     1475 
     1476    // two cases can occur: 
     1477    // (1) this packet has been received before iterate() was called (normal case). 
     1478    // (2) this packet has been received after iterate() was called. 
     1479    //     happens when the kernel flushes more packets while we are already processing. 
     1480    // 
     1481    // In case (1) now_cycles is a small number of cycles larger than cycle. In 
     1482    // case (2) now_cycles is a small number of cycles smaller than cycle. 
     1483    // hence  abs(diffCycles(now_cycles, cycles)) has to be 'small' 
     1484 
     1485    // we can calculate the time of arrival for this packet as 
     1486    // 'now' + diffCycles(cycles, now_cycles) * TICKS_PER_CYCLE 
     1487    // in its properly wrapped version 
     1488    int64_t diff_cycles = diffCycles(cycle, now_cycles); 
     1489    int64_t tmp = CYCLE_TIMER_TO_TICKS(m_last_now); 
     1490    tmp += diff_cycles * (int64_t)TICKS_PER_CYCLE; 
     1491    uint64_t pkt_ctr_ticks = wrapAtMinMaxTicks(tmp); 
     1492    uint32_t pkt_ctr = TICKS_TO_CYCLE_TIMER(pkt_ctr_ticks); 
     1493    #ifdef DEBUG 
     1494    if( (now_cycles < cycle) 
     1495        && diffCycles(now_cycles, cycle) < 0 
     1496        // ignore this on dropped cycles, since it's normal 
     1497        // that now is ahead on the received packets (as we miss packets) 
     1498        && dropped_cycles == 0)  
     1499    { 
     1500        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Special non-unwrapping happened\n"); 
     1501    } 
     1502    #endif 
     1503 
     1504    #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION 
     1505    // add a seconds field 
     1506    uint32_t now = m_manager.get1394Service().getCycleTimer(); 
     1507    uint32_t now_secs_ref = CYCLE_TIMER_GET_SECS(now); 
     1508    // causality results in the fact that 'now' is always after 'cycle' 
     1509    // or at best, equal (if this handler was called within 125us after 
     1510    // the packet was on the wire). 
     1511    if(CYCLE_TIMER_GET_CYCLES(now) < cycle) { 
     1512        // the cycle field has wrapped, substract one second 
     1513        if(now_secs_ref == 0) { 
     1514            now_secs_ref = 127; 
     1515        } else  { 
     1516            now_secs_ref -= 1; 
     1517        } 
     1518    } 
     1519    uint32_t pkt_ctr_ref = cycle << 12; 
     1520    pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25; 
     1521 
     1522    if((pkt_ctr & ~0x0FFFL) != pkt_ctr_ref) { 
     1523        debugWarning("reconstructed CTR counter discrepancy\n"); 
     1524        debugWarning(" ingredients: %X, %X, %X, %X, %X, %d, %ld, %ld, %"PRId64"\n", 
     1525                     cycle, pkt_ctr_ref, pkt_ctr,  
     1526                     now, m_last_now, now_secs_ref,  
     1527                     (long int)CYCLE_TIMER_GET_SECS(now), 
     1528                     (long int)CYCLE_TIMER_GET_SECS(m_last_now), 
     1529                     tmp); 
     1530        debugWarning(" diffcy = %"PRId64" \n", diff_cycles); 
     1531    } 
     1532    #endif 
     1533    m_last_packet_handled_at = pkt_ctr; 
     1534 
     1535    // leave the offset field (for now?) 
     1536 
     1537    debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 
     1538                "received packet: length=%d, channel=%d, cycle=%d, at %08X\n", 
     1539                length, channel, cycle, pkt_ctr); 
     1540    m_packets++; 
     1541    #ifdef DEBUG 
     1542    if (length > m_max_packet_size) { 
     1543        debugWarning("(%p, %s) packet too large: len=%u max=%u\n", 
     1544                     this, getTypeString(), length, m_max_packet_size); 
     1545    } 
     1546    if(m_last_cycle == -1) { 
     1547        debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %u)\n", getTypeString(), this, cycle); 
     1548    } 
     1549    #endif 
     1550 
     1551    // iterate the client if required 
     1552    if(m_Client) 
     1553        return m_Client->putPacket(data, length, channel, tag, sy, pkt_ctr, dropped_cycles); 
     1554 
     1555    return RAW1394_ISO_OK; 
     1556} 
     1557 
     1558enum raw1394_iso_disposition 
     1559IsoHandlerManager::IsoHandler::getPacket(unsigned char *data, unsigned int *length, 
     1560                      unsigned char *tag, unsigned char *sy, 
     1561                      int cycle, unsigned int dropped, unsigned int skipped) { 
     1562 
     1563    uint32_t pkt_ctr; 
     1564    if (cycle < 0) { 
     1565        // mark invalid 
     1566        pkt_ctr = 0xFFFFFFFF; 
     1567    } else { 
     1568        // the m_last_now value is set when the iterate() function is called. 
     1569        uint32_t now_cycles = CYCLE_TIMER_GET_CYCLES(m_last_now); 
     1570 
     1571        // two cases can occur: 
     1572        // (1) this packet has been received before iterate() was called (normal case). 
     1573        // (2) this packet has been received after iterate() was called. 
     1574        //     happens when the kernel flushes more packets while we are already processing. 
     1575        // 
     1576        // In case (1) now_cycles is a small number of cycles larger than cycle. In 
     1577        // case (2) now_cycles is a small number of cycles smaller than cycle. 
     1578        // hence  abs(diffCycles(now_cycles, cycles)) has to be 'small' 
     1579 
     1580        // we can calculate the time of arrival for this packet as 
     1581        // 'now' + diffCycles(cycles, now_cycles) * TICKS_PER_CYCLE 
     1582        // in its properly wrapped version 
     1583        int64_t diff_cycles = diffCycles(cycle, now_cycles); 
     1584        int64_t tmp = CYCLE_TIMER_TO_TICKS(m_last_now); 
     1585        tmp += diff_cycles * (int64_t)TICKS_PER_CYCLE; 
     1586        uint64_t pkt_ctr_ticks = wrapAtMinMaxTicks(tmp); 
     1587        pkt_ctr = TICKS_TO_CYCLE_TIMER(pkt_ctr_ticks); 
     1588 
     1589        #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION 
     1590        // add a seconds field 
     1591        uint32_t now = m_manager.get1394Service().getCycleTimer(); 
     1592        uint32_t now_secs_ref = CYCLE_TIMER_GET_SECS(now); 
     1593        // causality results in the fact that 'now' is always after 'cycle' 
     1594        if(CYCLE_TIMER_GET_CYCLES(now) > (unsigned int)cycle) { 
     1595            // the cycle field has wrapped, add one second 
     1596            now_secs_ref += 1; 
     1597            // no need for this: 
     1598            if(now_secs_ref == 128) { 
     1599               now_secs_ref = 0; 
     1600            } 
     1601        } 
     1602        uint32_t pkt_ctr_ref = cycle << 12; 
     1603        pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25; 
     1604 
     1605        if(((pkt_ctr & ~0x0FFFL) != pkt_ctr_ref) && (m_packets > m_buf_packets)) { 
     1606            debugWarning("reconstructed CTR counter discrepancy\n"); 
     1607            debugWarning(" ingredients: %X, %X, %X, %X, %X, %d, %ld, %ld, %"PRId64"\n", 
     1608                        cycle, pkt_ctr_ref, pkt_ctr, 
     1609                         now, m_last_now, now_secs_ref,  
     1610                         (long int)CYCLE_TIMER_GET_SECS(now), 
     1611                         (long int)CYCLE_TIMER_GET_SECS(m_last_now),  
     1612                         tmp); 
     1613            debugWarning(" diffcy = %"PRId64" \n", diff_cycles); 
     1614        } 
     1615        #endif 
     1616    } 
     1617    if (m_packets < m_buf_packets) { // these are still prebuffer packets 
     1618        m_last_packet_handled_at = 0xFFFFFFFF; 
     1619    } else { 
     1620        m_last_packet_handled_at = pkt_ctr; 
     1621    } 
     1622    debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 
     1623                "sending packet: length=%d, cycle=%d, at %08X\n", 
     1624                *length, cycle, pkt_ctr); 
     1625 
     1626    m_packets++; 
     1627 
     1628    #ifdef DEBUG 
     1629    if(m_last_cycle == -1) { 
     1630        debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %d)\n", getTypeString(), this, cycle); 
     1631    } 
     1632    #endif 
     1633 
     1634    // keep track of dropped cycles 
     1635    int dropped_cycles = 0; 
     1636    if (m_last_cycle != cycle && m_last_cycle != -1) { 
     1637        dropped_cycles = diffCycles(cycle, m_last_cycle) - 1; 
     1638        // correct for skipped packets 
     1639        // since those are not dropped, but only delayed 
     1640        dropped_cycles -= skipped; 
     1641 
     1642        #ifdef DEBUG 
     1643        if(skipped) { 
     1644            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 
     1645                        "(%p) skipped %d cycles, cycle: %d, last_cycle: %d, dropped: %d\n",  
     1646                        this, skipped, cycle, m_last_cycle, dropped); 
     1647            m_skipped += skipped; 
     1648        } 
     1649        if (dropped_cycles < 0) {  
     1650            debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d, skipped: %d\n",  
     1651                         this, dropped_cycles, cycle, m_last_cycle, dropped, skipped); 
     1652        } 
     1653        if (dropped_cycles > 0) { 
     1654            debugOutput(DEBUG_LEVEL_VERBOSE, 
     1655                        "(%p) dropped %d packets on cycle %u (last_cycle=%u, dropped=%d, skipped: %d)\n", 
     1656                        this, dropped_cycles, cycle, m_last_cycle, dropped, skipped); 
     1657            m_dropped += dropped_cycles - skipped; 
     1658        } 
     1659        #endif 
     1660    } 
     1661    if (cycle >= 0) { 
     1662        m_last_cycle = cycle; 
     1663         
     1664        #ifdef DEBUG 
     1665/*        int ahead = diffCycles(cycle, now_cycles); 
     1666        if (ahead < m_min_ahead) m_min_ahead = ahead; 
     1667*/ 
     1668        #endif 
     1669    } 
     1670 
     1671    #ifdef DEBUG 
     1672    if (dropped > 0) { 
     1673        debugOutput(DEBUG_LEVEL_VERBOSE, 
     1674                    "(%p) OHCI issue on cycle %u (dropped_cycles=%d, last_cycle=%u, dropped=%d, skipped: %d)\n", 
     1675                    this, cycle, dropped_cycles, m_last_cycle, dropped, skipped); 
     1676    } 
     1677    #endif 
     1678 
     1679    if(m_Client) { 
     1680        enum raw1394_iso_disposition retval; 
     1681        retval = m_Client->getPacket(data, length, tag, sy, pkt_ctr, dropped_cycles, skipped, m_max_packet_size); 
     1682        #ifdef DEBUG 
     1683        if (*length > m_max_packet_size) { 
     1684            debugWarning("(%p, %s) packet too large: len=%u max=%u\n", 
     1685                         this, getTypeString(), *length, m_max_packet_size); 
     1686        } 
     1687        #endif 
     1688            return retval; 
     1689    } 
     1690 
     1691    *tag = 0; 
     1692    *sy = 0; 
     1693    *length = 0; 
     1694    return RAW1394_ISO_OK; 
     1695} 
     1696 
     1697bool 
     1698IsoHandlerManager::IsoHandler::enable(int cycle) 
     1699{ 
     1700    debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d\n", cycle); 
     1701 
     1702    // check the state 
     1703    if(m_State != eHS_Stopped) { 
     1704        debugError("Incorrect state, expected eHS_Stopped, got %d\n",(int)m_State); 
     1705        return false; 
     1706    } 
     1707 
     1708    assert(m_handle == NULL); 
     1709 
     1710    // create a handle for the ISO traffic 
     1711    m_handle = raw1394_new_handle_on_port( m_manager.get1394Service().getPort() ); 
     1712    if ( !m_handle ) { 
     1713        if ( !errno ) { 
     1714            debugError("libraw1394 not compatible\n"); 
     1715        } else { 
     1716            debugError("Could not get 1394 handle: %s\n", strerror(errno) ); 
     1717            debugError("Are ieee1394 and raw1394 drivers loaded?\n"); 
     1718        } 
     1719        return false; 
     1720    } 
     1721    raw1394_set_userdata(m_handle, static_cast<void *>(this)); 
     1722 
     1723    // prepare the handler, allocate the resources 
     1724    debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso handler (%p, client=%p)\n", this, m_Client); 
     1725    dumpInfo(); 
     1726    if (getType() == eHT_Receive) { 
     1727        if(raw1394_iso_recv_init(m_handle, 
     1728                                iso_receive_handler, 
     1729                                m_buf_packets, 
     1730                                m_max_packet_size, 
     1731                                m_Client->getChannel(), 
     1732                                m_receive_mode, 
     1733                                m_irq_interval)) { 
     1734            debugFatal("Could not do receive initialization (PACKET_PER_BUFFER)!\n" ); 
     1735            debugFatal("  %s\n",strerror(errno)); 
     1736            return false; 
     1737        } 
     1738 
     1739        if(raw1394_iso_recv_start(m_handle, cycle, -1, 0)) { 
     1740            debugFatal("Could not start receive handler (%s)\n",strerror(errno)); 
     1741            dumpInfo(); 
     1742            return false; 
     1743        } 
     1744    } else { 
     1745        if(raw1394_iso_xmit_init(m_handle, 
     1746                                iso_transmit_handler, 
     1747                                m_buf_packets, 
     1748                                m_max_packet_size, 
     1749                                m_Client->getChannel(), 
     1750                                m_speed, 
     1751                                m_irq_interval)) { 
     1752            debugFatal("Could not do xmit initialisation!\n" ); 
     1753            return false; 
     1754        } 
     1755 
     1756        if(raw1394_iso_xmit_start(m_handle, cycle, 0)) { 
     1757            debugFatal("Could not start xmit handler (%s)\n", strerror(errno)); 
     1758            dumpInfo(); 
     1759            return false; 
     1760        } 
     1761    } 
     1762 
     1763#ifdef DEBUG 
     1764    m_min_ahead = 7999; 
     1765#endif 
     1766 
     1767    m_packets = 0; 
     1768 
     1769    // indicate that the first iterate() still has to occur. 
     1770    m_last_now = 0xFFFFFFFF; 
     1771    m_last_packet_handled_at = 0xFFFFFFFF; 
     1772 
     1773    m_State = eHS_Running; 
     1774    m_NextState = eHS_Running; 
     1775    return true; 
     1776} 
     1777 
     1778bool 
     1779IsoHandlerManager::IsoHandler::disable() 
     1780{ 
     1781    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) enter...\n",  
     1782                 this, (m_type==eHT_Receive?"Receive":"Transmit")); 
     1783 
     1784    // check state 
     1785    if(m_State != eHS_Running) { 
     1786        debugError("Incorrect state, expected eHS_Running, got %d\n",(int)m_State); 
     1787        return false; 
     1788    } 
     1789 
     1790    assert(m_handle != NULL); 
     1791 
     1792    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) wake up handle...\n",  
     1793                 this, (m_type==eHT_Receive?"Receive":"Transmit")); 
     1794 
     1795    // wake up any waiting reads/polls 
     1796    raw1394_wake_up(m_handle); 
     1797 
     1798    // this is put here to try and avoid the 
     1799    // Runaway context problem 
     1800    // don't know if it will help though. 
     1801/*    if(m_State != eHS_Error) { // if the handler is dead, this might block forever 
     1802        raw1394_iso_xmit_sync(m_handle); 
     1803    }*/ 
     1804    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) stop...\n",  
     1805                 this, (m_type==eHT_Receive?"Receive":"Transmit")); 
     1806    // stop iso traffic 
     1807    raw1394_iso_stop(m_handle); 
     1808    // deallocate resources 
     1809 
     1810    // Don't call until libraw1394's raw1394_new_handle() function has been 
     1811    // fixed to correctly initialise the iso_packet_infos field.  Bug is 
     1812    // confirmed present in libraw1394 1.2.1. 
     1813    raw1394_iso_shutdown(m_handle); 
     1814 
     1815    raw1394_destroy_handle(m_handle); 
     1816    m_handle = NULL; 
     1817 
     1818    m_State = eHS_Stopped; 
     1819    m_NextState = eHS_Stopped; 
     1820    return true; 
     1821} 
     1822 
     1823// functions to request enable or disable at the next opportunity 
     1824bool 
     1825IsoHandlerManager::IsoHandler::requestEnable(int cycle) 
     1826{ 
     1827    if (m_State == eHS_Running) { 
     1828        debugError("Enable requested on enabled stream\n"); 
     1829        return false; 
     1830    } 
     1831    if (m_State != eHS_Stopped) { 
     1832        debugError("Enable requested on stream with state: %d\n", m_State); 
     1833        return false; 
     1834    } 
     1835    m_NextState = eHS_Running; 
     1836    return true; 
     1837} 
     1838 
     1839bool 
     1840IsoHandlerManager::IsoHandler::requestDisable() 
     1841{ 
     1842    if (m_State == eHS_Stopped) { 
     1843        debugError("Disable requested on disabled stream\n"); 
     1844        return false; 
     1845    } 
     1846    if (m_State != eHS_Running) { 
     1847        debugError("Disable requested on stream with state=%d\n", m_State); 
     1848        return false; 
     1849    } 
     1850    m_NextState = eHS_Stopped; 
     1851    return true; 
     1852} 
     1853 
     1854void 
     1855IsoHandlerManager::IsoHandler::updateState() 
     1856{ 
     1857    // execute state changes requested 
     1858    if(m_State != m_NextState) { 
     1859        debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) handler needs state update from %d => %d\n", this, m_State, m_NextState); 
     1860        if(m_State == eHS_Stopped && m_NextState == eHS_Running) { 
     1861            debugOutput(DEBUG_LEVEL_VERBOSE, "handler has to be enabled\n"); 
     1862            enable(m_switch_on_cycle); 
     1863        } else if(m_State == eHS_Running && m_NextState == eHS_Stopped) { 
     1864            debugOutput(DEBUG_LEVEL_VERBOSE, "handler has to be disabled\n"); 
     1865            disable(); 
     1866        } else { 
     1867            debugError("Unknown state transition\n"); 
     1868        } 
     1869    } 
     1870} 
     1871 
     1872/** 
     1873 * @brief convert a EHandlerType to a string 
     1874 * @param t the type 
     1875 * @return a char * describing the state 
     1876 */ 
     1877const char * 
     1878IsoHandlerManager::IsoHandler::eHTToString(enum EHandlerType t) { 
     1879    switch (t) { 
     1880        case eHT_Receive: return "Receive"; 
     1881        case eHT_Transmit: return "Transmit"; 
     1882        default: return "error: unknown type"; 
     1883    } 
     1884} 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.h

    r1531 r1765  
    3030 
    3131#include "libutil/Thread.h" 
    32  
    33 #include "IsoHandler.h" 
    3432 
    3533#include <sys/poll.h> 
     
    4745    typedef std::vector<StreamProcessor *>::iterator StreamProcessorVectorIterator; 
    4846} 
    49  
    50 typedef std::vector<IsoHandler *> IsoHandlerVector; 
    51 typedef std::vector<IsoHandler *>::iterator IsoHandlerVectorIterator; 
    52  
    53 class IsoHandlerManager; 
    54  
    55 // threads that will handle the packet framing 
    56 // one thread per direction, as a compromise for one per 
    57 // channel and one for all 
    58 class IsoTask : public Util::RunnableInterface 
    59 { 
    60     friend class IsoHandlerManager; 
    61     public: 
    62         IsoTask(IsoHandlerManager& manager, enum IsoHandler::EHandlerType); 
    63         virtual ~IsoTask(); 
    64  
    65     public: 
    66         bool Init(); 
    67         bool Execute(); 
    68  
    69         /** 
    70          * @brief requests the thread to sync it's stream map with the manager 
    71          */ 
    72         void requestShadowMapUpdate(); 
    73         enum eActivityResult { 
    74             eAR_Activity, 
    75             eAR_Timeout, 
    76             eAR_Interrupted, 
    77             eAR_Error 
    78         }; 
    79  
    80         /** 
    81          * @brief signals that something happened in one of the clients of this task 
    82          */ 
    83         void signalActivity(); 
    84         /** 
    85          * @brief wait until something happened in one of the clients of this task 
    86          */ 
    87         enum eActivityResult waitForActivity(); 
    88  
    89         /** 
    90          * @brief This should be called when a busreset has happened. 
    91          */ 
    92         bool handleBusReset(); 
    93  
    94         void setVerboseLevel(int i); 
    95     protected: 
    96         IsoHandlerManager& m_manager; 
    97  
    98         // the event request structure 
    99         int32_t request_update; 
    100  
    101         // static allocation due to RT constraints 
    102         // this is the map used by the actual thread 
    103         // it is a shadow of the m_StreamProcessors vector 
    104         struct pollfd   m_poll_fds_shadow[ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT]; 
    105         IsoHandler *    m_IsoHandler_map_shadow[ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT]; 
    106         unsigned int    m_poll_nfds_shadow; 
    107         IsoHandler *    m_SyncIsoHandler; 
    108  
    109         // updates the streams map 
    110         void updateShadowMapHelper(); 
    111  
    112 #ifdef DEBUG 
    113         uint64_t m_last_loop_entry; 
    114         int m_successive_short_loops; 
    115 #endif 
    116  
    117         enum IsoHandler::EHandlerType m_handlerType; 
    118         bool m_running; 
    119         bool m_in_busreset; 
    120  
    121         // activity signaling 
    122         sem_t m_activity_semaphore; 
    123         long long int m_activity_wait_timeout_nsec; 
    124  
    125         // debug stuff 
    126         DECLARE_DEBUG_MODULE; 
    127 }; 
    12847 
    12948/*! 
     
    14362    friend class IsoTask; 
    14463 
     64//// 
     65/*! 
     66    \brief The Base Class for ISO Handlers 
     67 
     68    These classes perform the actual ISO communication through libraw1394. 
     69    They are different from Streaming::StreamProcessors because one handler can provide multiple 
     70    streams with packets in case of ISO multichannel receive. 
     71 
     72 */ 
     73 
     74    class IsoHandler 
     75    { 
     76        public: 
     77            enum EHandlerType { 
     78                eHT_Receive, 
     79                eHT_Transmit 
     80            }; 
     81            IsoHandler(IsoHandlerManager& manager, enum EHandlerType t); 
     82            IsoHandler(IsoHandlerManager& manager, enum EHandlerType t, 
     83                       unsigned int buf_packets, unsigned int max_packet_size, int irq); 
     84            IsoHandler(IsoHandlerManager& manager, enum EHandlerType t, 
     85                       unsigned int buf_packets, unsigned int max_packet_size, int irq, enum raw1394_iso_speed speed); 
     86            ~IsoHandler(); 
     87 
     88            private: // the ISO callback interface 
     89                static enum raw1394_iso_disposition 
     90                        iso_receive_handler(raw1394handle_t handle, unsigned char *data, 
     91                                            unsigned int length, unsigned char channel, 
     92                                            unsigned char tag, unsigned char sy, unsigned int cycle, 
     93                                            unsigned int dropped); 
     94 
     95                enum raw1394_iso_disposition 
     96                        putPacket(unsigned char *data, unsigned int length, 
     97                                  unsigned char channel, unsigned char tag, unsigned char sy, 
     98                                  unsigned int cycle, unsigned int dropped); 
     99 
     100                static enum raw1394_iso_disposition iso_transmit_handler(raw1394handle_t handle, 
     101                        unsigned char *data, unsigned int *length, 
     102                        unsigned char *tag, unsigned char *sy, 
     103                        int cycle, unsigned int dropped); 
     104                enum raw1394_iso_disposition 
     105                        getPacket(unsigned char *data, unsigned int *length, 
     106                                  unsigned char *tag, unsigned char *sy, 
     107                                  int cycle, unsigned int dropped, unsigned int skipped); 
     108 
     109        public: 
     110 
     111    /** 
     112         * Iterate the handler, transporting ISO packets to the client(s) 
     113         * @return true if success 
     114     */ 
     115            bool iterate(); 
     116 
     117    /** 
     118             * Iterate the handler, transporting ISO packets to the client(s) 
     119             * @param  ctr_now the CTR time at which the iterate call is done. 
     120             * @return true if success 
     121     */ 
     122            bool iterate(uint32_t ctr_now); 
     123 
     124            int getFileDescriptor() { return raw1394_get_fd(m_handle);}; 
     125 
     126            bool init(); 
     127            void setVerboseLevel(int l); 
     128 
     129    // the enable/disable functions should only be used from within the loop that iterates() 
     130    // but not from within the iterate callback. use the requestEnable / requestDisable functions 
     131    // for that 
     132            bool enable() {return enable(-1);}; 
     133            bool enable(int cycle); 
     134            bool disable(); 
     135 
     136    // functions to request enable or disable at the next opportunity 
     137            bool requestEnable(int cycle = -1); 
     138            bool requestDisable(); 
     139 
     140    /** 
     141             * updates the internal state if required 
     142     */ 
     143            void updateState(); 
     144 
     145            enum EHandlerType getType() {return m_type;}; 
     146            const char *getTypeString() {return eHTToString(m_type); }; 
     147 
     148    // pretty printing 
     149            const char *eHTToString(enum EHandlerType); 
     150 
     151            bool isEnabled() 
     152            {return m_State == eHS_Running;}; 
     153 
     154    // no setter functions, because those would require a re-init 
     155            unsigned int getMaxPacketSize() { return m_max_packet_size;}; 
     156            unsigned int getNbBuffers() { return m_buf_packets;}; 
     157            int getIrqInterval() { return m_irq_interval;}; 
     158 
     159            void dumpInfo(); 
     160 
     161            bool inUse() {return (m_Client != 0) ;}; 
     162            bool isStreamRegistered(Streaming::StreamProcessor *s) {return (m_Client == s);}; 
     163 
     164            bool registerStream(Streaming::StreamProcessor *); 
     165            bool unregisterStream(Streaming::StreamProcessor *); 
     166 
     167            bool canIterateClient(); // FIXME: implement with functor 
     168 
     169 
     170    /** 
     171             * @brief get last cycle number seen by handler 
     172             * @return cycle number 
     173     */ 
     174            int getLastCycle() {return m_last_cycle;}; 
     175 
     176    /** 
     177             * @brief returns the CTR value saved at the last iterate() call 
     178             * @return CTR value saved at last iterate() call 
     179     */ 
     180            uint32_t getLastIterateTime() {return m_last_now;}; 
     181 
     182    /** 
     183             * @brief returns the CTR value saved at the last iterate handler call 
     184             * @return CTR value saved at last iterate handler call 
     185     */ 
     186            uint32_t getLastPacketTime() {return m_last_packet_handled_at;}; 
     187 
     188    /** 
     189             * @brief set iso receive mode. doesn't have any effect if the stream is running 
     190             * @param m receive mode 
     191     */ 
     192            void setReceiveMode(enum raw1394_iso_dma_recv_mode m) 
     193            {m_receive_mode = m;} 
     194 
     195            void notifyOfDeath(); 
     196            bool handleBusReset(); 
     197 
     198        private: 
     199            IsoHandlerManager& m_manager; 
     200            enum EHandlerType m_type; 
     201            raw1394handle_t m_handle; 
     202            unsigned int    m_buf_packets; 
     203            unsigned int    m_max_packet_size; 
     204            int             m_irq_interval; 
     205            int             m_last_cycle; 
     206            uint32_t        m_last_now; 
     207            uint32_t        m_last_packet_handled_at; 
     208            enum raw1394_iso_dma_recv_mode m_receive_mode; 
     209 
     210            Streaming::StreamProcessor *m_Client; // FIXME: implement with functors 
     211 
     212            enum raw1394_iso_speed m_speed; 
     213 
     214    // the state machine 
     215            enum EHandlerStates { 
     216                eHS_Stopped, 
     217                eHS_Running, 
     218                eHS_Error, 
     219            }; 
     220            enum EHandlerStates m_State; 
     221            enum EHandlerStates m_NextState; 
     222            int m_switch_on_cycle; 
     223 
     224        public: 
     225            unsigned int    m_packets; 
     226#ifdef DEBUG 
     227            unsigned int    m_dropped; 
     228            unsigned int    m_skipped; 
     229            int             m_min_ahead; 
     230#endif 
     231 
     232        protected: 
     233            DECLARE_DEBUG_MODULE; 
     234    }; 
     235 
     236    typedef std::vector<IsoHandler *> IsoHandlerVector; 
     237    typedef std::vector<IsoHandler *>::iterator IsoHandlerVectorIterator; 
     238 
     239//// 
     240     
     241// threads that will handle the packet framing 
     242// one thread per direction, as a compromise for one per 
     243// channel and one for all 
     244    class IsoTask : public Util::RunnableInterface 
     245    { 
     246        friend class IsoHandlerManager; 
     247        public: 
     248            IsoTask(IsoHandlerManager& manager, enum IsoHandler::EHandlerType); 
     249            virtual ~IsoTask(); 
     250 
     251        private: 
     252            bool Init(); 
     253            bool Execute(); 
     254 
     255        /** 
     256             * @brief requests the thread to sync it's stream map with the manager 
     257         */ 
     258            void requestShadowMapUpdate(); 
     259            enum eActivityResult { 
     260                eAR_Activity, 
     261                eAR_Timeout, 
     262                eAR_Interrupted, 
     263                eAR_Error 
     264            }; 
     265 
     266        /** 
     267             * @brief signals that something happened in one of the clients of this task 
     268         */ 
     269            void signalActivity(); 
     270        /** 
     271             * @brief wait until something happened in one of the clients of this task 
     272         */ 
     273            enum eActivityResult waitForActivity(); 
     274 
     275        /** 
     276             * @brief This should be called when a busreset has happened. 
     277         */ 
     278            bool handleBusReset(); 
     279 
     280            void setVerboseLevel(int i); 
     281 
     282        protected: 
     283            IsoHandlerManager& m_manager; 
     284 
     285        // the event request structure 
     286            int32_t request_update; 
     287 
     288        // static allocation due to RT constraints 
     289        // this is the map used by the actual thread 
     290        // it is a shadow of the m_StreamProcessors vector 
     291            struct pollfd   m_poll_fds_shadow[ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT]; 
     292            IsoHandler *    m_IsoHandler_map_shadow[ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT]; 
     293            unsigned int    m_poll_nfds_shadow; 
     294            IsoHandler *    m_SyncIsoHandler; 
     295 
     296        // updates the streams map 
     297            void updateShadowMapHelper(); 
     298 
     299#ifdef DEBUG 
     300            uint64_t m_last_loop_entry; 
     301            int m_successive_short_loops; 
     302#endif 
     303 
     304            enum IsoHandler::EHandlerType m_handlerType; 
     305            bool m_running; 
     306            bool m_in_busreset; 
     307 
     308        // activity signaling 
     309            sem_t m_activity_semaphore; 
     310            long long int m_activity_wait_timeout_nsec; 
     311 
     312        // debug stuff 
     313            DECLARE_DEBUG_MODULE; 
     314    }; 
     315     
     316//// the IsoHandlerManager itself 
    145317    public: 
    146318 
     
    154326 
    155327        void dumpInfo(); ///< print some information about the manager to stdout/stderr 
     328        void dumpInfoForStream(Streaming::StreamProcessor *); ///< print some info about the stream's handler 
    156329 
    157330        bool registerStream(Streaming::StreamProcessor *); ///< register an iso stream with the manager 
     
    185358         */ 
    186359        int getPacketLatencyForStream(Streaming::StreamProcessor *); 
    187  
     360    private: 
    188361        IsoHandler * getHandlerForStream(Streaming::StreamProcessor *stream); 
    189  
     362        void requestShadowMapUpdate(); 
     363    public: 
    190364        Ieee1394Service& get1394Service() {return m_service;}; 
    191  
    192         void requestShadowMapUpdate(); 
    193365 
    194366        /** 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

    r1763 r1765  
    2121 * 
    2222 */ 
    23  
    24  
    2523 
    2624#include "StreamProcessor.h" 
     
    18931891    debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor %p, %s:\n", this, ePTToString(m_processor_type)); 
    18941892    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel    : %d, %d\n", m_1394service.getPort(), m_channel); 
    1895     IsoHandler *h = m_IsoHandlerManager.getHandlerForStream(this); 
    1896     if (h) { 
    1897         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Packets, Dropped, Skipped : %d, %d, %d\n", 
    1898                                               h->m_packets, h->m_dropped, h->m_skipped); 
    1899     } else { 
    1900         debugError("No handler for stream??\n"); 
    1901     } 
     1893    m_IsoHandlerManager.dumpInfoForStream(this); 
    19021894    uint64_t now = m_1394service.getCycleTimerTicks(); 
    19031895    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Now                   : %011"PRIu64" (%03us %04uc %04ut)\n", 
  • trunk/libffado/src/SConscript

    r1763 r1765  
    4242        libieee1394/ieee1394service.cpp \ 
    4343        libieee1394/IEC61883.cpp \ 
    44         libieee1394/IsoHandler.cpp \ 
    4544        libieee1394/IsoHandlerManager.cpp \ 
    4645        libstreaming/StreamProcessorManager.cpp \ 
  • trunk/libffado/tests/test-scs.cpp

    r1763 r1765  
    325325        virtual void operator() (byte_t *buff, size_t len) { 
    326326            if (m_ready) { 
    327                 debugOutput(DEBUG_LEVEL_NORMAL, "got message len %zd\n", len); 
     327                debugOutput(DEBUG_LEVEL_VERBOSE, 
     328                            "got message len %zd\n", 
     329                            len); 
    328330     
    329331                for (size_t s=0; s < len; s++) {