Changeset 290

Show
Ignore:
Timestamp:
07/13/06 17:42:27 (16 years ago)
Author:
jwoithe
Message:

Iso resources (channels, bandwidth) now allocated via the IRM.
Some comments clarified.
Minor code cleanups.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/libfreebob-2.0/src/motu/motu_avdevice.cpp

    r283 r290  
    3838#include <netinet/in.h> 
    3939 
     40#include <libraw1394/csr.h> 
     41 
    4042namespace Motu { 
    4143 
     
    4547 
    4648/* ======================================================================= */ 
    47 /* Provide a mechanism for allocating iso channels to MOTU interfaces. 
    48  * 
    49  * FIXME: This is overly simplistic at present since it assumes there are no 
    50  * other users of iso channels on the firewire bus except MOTU interfaces.  
    51  * It does however allow more than one MOTU interface to exist on the same 
    52  * bus.  For now the first MOTU discovered will be allocated iso channels 0 
    53  * (send) and 1 (receive) which mirrors what the official driver appears to 
    54  * do.  Ultimately we need code to query the IRM for iso channels. 
     49/* Provide a mechanism for allocating iso channels and bandwidth to MOTU  
     50 * interfaces. 
    5551 */ 
    56 static signed int next_iso_recv_channel_num = 1; 
    57 static signed int next_iso_send_channel_num = 0;   
    58        
    59 static signed int next_iso_recv_channel(void) { 
     52 
     53static signed int allocate_iso_channel(raw1394handle_t handle) { 
    6054/* 
    61  * Returns the next available channel for ISO receive.  If there are no more 
    62  * available -1 is returned.  Currently the odd channels (starting from 1
    63  * are used for iso receive.  No provision is made to reuse previously 
    64  * allocated channels in the event that the applicable interface has been 
    65  * removed - this will change in future to use the IRM
     55 * Allocates an iso channel for use by the interface in a similar way to 
     56 * libiec61883.  Returns -1 on error (due to there being no free channels
     57 * or an allocated channel number. 
     58 * FIXME: As in libiec61883, channel 63 is not requested; this is either a 
     59 * bug or it's omitted since that's the channel preferred by video devices
    6660 */ 
    67         if (next_iso_recv_channel_num < 64) { 
    68                 next_iso_recv_channel_num+=2; 
    69                 return next_iso_recv_channel_num-2; 
    70         } 
     61        int c = -1; 
     62        for (c = 0; c < 63; c++) 
     63                if (raw1394_channel_modify (handle, c, RAW1394_MODIFY_ALLOC) == 0) 
     64                        break; 
     65        if (c < 63) 
     66                return c; 
    7167        return -1; 
    7268} 
    73 static signed int next_iso_send_channel(void) { 
     69 
     70static signed int free_iso_channel(raw1394handle_t handle, signed int channel) { 
    7471/* 
    75  * Returns the next available channel for ISO send.  If there are no more 
    76  * available -1 is returned.  Currently the even channels (starting from 0) 
    77  * are used for iso receive.  No provision is made to reuse previously 
    78  * allocated channels in the event that the applicable interface has been 
    79  * removed - this will all change in future to use the IRM. 
     72 * Deallocates an iso channel.  Returns -1 on error or 0 on success.  Silently 
     73 * ignores a request to deallocate a negative channel number. 
    8074 */ 
    81         if (next_iso_send_channel_num < 64) { 
    82                 next_iso_send_channel_num+=2; 
    83                 return next_iso_send_channel_num-2; 
    84         } 
    85         return -1; 
     75        if (channel < 0) 
     76                return 0; 
     77        if (raw1394_channel_modify (handle, channel, RAW1394_MODIFY_FREE)!=0) 
     78                return -1; 
     79        return 0; 
     80
     81 
     82static signed int get_iso_bandwidth_avail(raw1394handle_t handle) { 
     83/* 
     84 * Returns the current value of the `bandwidth available' register on 
     85 * the IRM, or -1 on error. 
     86 */ 
     87quadlet_t buffer; 
     88signed int result = raw1394_read (handle, raw1394_get_irm_id (handle), 
     89        CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, 
     90        sizeof (quadlet_t), &buffer); 
     91 
     92        if (result < 0) 
     93                return -1; 
     94        return ntohl(buffer); 
    8695} 
    8796/* ======================================================================= */ 
     
    97106    , m_iso_recv_channel ( -1 ) 
    98107    , m_iso_send_channel ( -1 ) 
     108    , m_bandwidth ( -1 ) 
    99109    , m_receiveProcessor ( 0 ) 
    100110    , m_transmitProcessor ( 0 ) 
     
    113123MotuDevice::~MotuDevice() 
    114124{ 
     125        // Free ieee1394 bus resources if they have been allocated 
     126        if (m_1394Service != NULL) { 
     127                raw1394handle_t handle = m_1394Service->getHandle(); 
     128                if (m_bandwidth >= 0) 
     129                        if (raw1394_bandwidth_modify(handle, m_bandwidth, RAW1394_MODIFY_FREE) < 0) 
     130                                debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free bandwidth of %d\n", m_bandwidth); 
     131                if (m_iso_recv_channel >= 0) 
     132                        if (raw1394_channel_modify(handle, m_iso_recv_channel, RAW1394_MODIFY_FREE) < 0) 
     133                                debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free recv iso channel %d\n", m_iso_recv_channel); 
     134                if (m_iso_send_channel >= 0) 
     135                        if (raw1394_channel_modify(handle, m_iso_send_channel, RAW1394_MODIFY_FREE) < 0) 
     136                                debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free send iso channel %d\n", m_iso_send_channel); 
     137        } 
    115138        delete m_configRom; 
    116139} 
     
    139162                debugOutput( DEBUG_LEVEL_VERBOSE, "found MOTU %s\n", 
    140163                        motufw_modelname[m_motu_model]); 
    141  
    142                 // Assign iso channels if not already done 
    143                 if (m_iso_recv_channel < 0) 
    144                         m_iso_recv_channel = next_iso_recv_channel(); 
    145                 if (m_iso_send_channel < 0) 
    146                         m_iso_send_channel = next_iso_send_channel(); 
    147164                return true; 
    148165        } 
     166 
    149167        return false; 
    150168} 
     
    255273        unsigned int event_size = getEventSize(); 
    256274 
     275        raw1394handle_t handle = m_1394Service->getHandle(); 
     276 
    257277        debugOutput(DEBUG_LEVEL_NORMAL, "Preparing MotuDevice...\n" ); 
     278 
     279        // Assign iso channels if not already done 
     280        if (m_iso_recv_channel < 0) 
     281                m_iso_recv_channel = allocate_iso_channel(handle); 
     282        if (m_iso_send_channel < 0) 
     283                m_iso_send_channel = allocate_iso_channel(handle); 
     284 
     285        debugOutput(DEBUG_LEVEL_VERBOSE, "recv channel = %d, send channel = %d\n", 
     286                m_iso_recv_channel, m_iso_send_channel); 
     287 
     288        if (m_iso_recv_channel<0 || m_iso_send_channel<0) { 
     289                debugFatal("Could not allocate iso channels!\n"); 
     290                return false; 
     291        } 
     292 
     293        // Allocate bandwidth if not previously done. 
     294        // FIXME: The bandwidth allocation calculation can probably be 
     295        // refined somewhat since this is currently based on a rudimentary 
     296        // understanding of the iso protocol. 
     297        // Currently we assume the following. 
     298        //   * Ack/iso gap = 0.05 us 
     299        //   * DATA_PREFIX = 0.16 us 
     300        //   * DATA_END    = 0.26 us 
     301        // These numbers are the worst-case figures given in the ieee1394 
     302        // standard.  This gives approximately 0.5 us of overheads per 
     303        // packet - around 25 bandwidth allocation units (from the ieee1394 
     304        // standard 1 bandwidth allocation unit is 125/6144 us).  We further 
     305        // assume the MOTU is running at S400 (which it should be) so one 
     306        // allocation unit is equivalent to 1 transmitted byte; thus the 
     307        // bandwidth allocation required for the packets themselves is just 
     308        // the size of the packet.  We allocate based on the maximum packet 
     309        // size (1160 bytes at 192 kHz) so the sampling frequency can be 
     310        // changed dynamically if this ends up being useful in future. 
     311        m_bandwidth = 25 + 1160; 
     312        debugOutput(DEBUG_LEVEL_VERBOSE, "Available bandwidth: %d\n",  
     313                get_iso_bandwidth_avail(handle)); 
     314        if (raw1394_bandwidth_modify(handle, m_bandwidth, RAW1394_MODIFY_ALLOC) < 0) { 
     315                debugFatal("Could not allocate bandwidth of %d\n", m_bandwidth); 
     316                m_bandwidth = -1; 
     317                return false; 
     318        } 
     319        debugOutput(DEBUG_LEVEL_VERBOSE,  
     320                "allocated bandwidth of %d for MOTU device\n", m_bandwidth); 
     321        debugOutput(DEBUG_LEVEL_VERBOSE, 
     322                "remaining bandwidth: %d\n", get_iso_bandwidth_avail(handle)); 
    258323 
    259324        m_receiveProcessor=new FreebobStreaming::MotuReceiveStreamProcessor( 
    260325                m_1394Service->getPort(), samp_freq, event_size); 
    261326                                  
    262         // the first thing is to initialize the processor 
    263         // this creates the data structures 
     327        // The first thing is to initialize the processor.  This creates the 
     328        // data structures. 
    264329        if(!m_receiveProcessor->init()) { 
    265330                debugFatal("Could not initialize receive processor!\n"); 
     
    268333        m_receiveProcessor->setVerboseLevel(getDebugLevel()); 
    269334 
    270         // now we add ports to the processor 
     335        // Now we add ports to the processor 
    271336        debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to receive processor\n"); 
    272337         
    273         // TODO: change this into something based upon device detection/configuration 
    274338        char *buff; 
    275339        unsigned int i; 
     
    324388//    } 
    325389 
    326         // do the same for the transmit processor 
     390        // Do the same for the transmit processor 
    327391        m_transmitProcessor=new FreebobStreaming::MotuTransmitStreamProcessor( 
    328392                m_1394Service->getPort(), getSamplingFrequency(), event_size); 
     
    339403        m_transmitProcessor->set_sph_ofs_dll(m_receiveProcessor->get_sph_ofs_dll()); 
    340404 
    341         // now we add ports to the processor 
     405        // Now we add ports to the processor 
    342406        debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to transmit processor\n"); 
    343407 
  • branches/libfreebob-2.0/src/motu/motu_avdevice.h

    r272 r290  
    103103    signed int m_id; 
    104104    signed int m_iso_recv_channel, m_iso_send_channel; 
     105    signed int m_bandwidth; 
    105106     
    106107        FreebobStreaming::MotuReceiveStreamProcessor *m_receiveProcessor;