10.02_devices/2_src/uda.cpp
//
// worker():
//  Implements the initialization state machine.
//
Implements the initialization state machine.
Implements the initialization state machine .
void uda_c::worker(unsigned instance)
{
    UNUSED(instance) ; 
    worker_init_realtime_priority(rt_device); 
    timeout_c timeout;
    while (!workers_terminate)
    {
         Wait to be awoken.
        pthread_mutex_lock(&on_after_register_access_mutex);
        while (!_next_step)
        {
            pthread_cond_wait(
                &on_after_register_access_cond,
                &on_after_register_access_mutex);
        }
        _next_step = false;
        pthread_mutex_unlock(&on_after_register_access_mutex);
        switch (_initStep)
        {
            case InitializationStep::Uninitialized:
                 DEBUG("Transition to Init state Uninitialized."); 
                  SA should already be zero but we'll be extra sure here.
                 update_SA(0x0);
                  Reset the controller: This may take some time as we must
                  wait for the MSCP server to wrap up its current workitem.
                 Reset();
                 StateTransition(InitializationStep::Step1);
                 break;                
            case InitializationStep::Step1:
                 timeout.wait_us(500);  
                 DEBUG("Transition to Init state S1.");
                  S1 is set, all other bits zero.  This indicates that we
                  support a host-settable interrupt vector, that we do not
                  implement enhanced diagnostics, and that no errors have
                  occurred.
                 DEBUG("22 bit dma is %d", _22bitDMA);
                 update_SA(STEP1 | (_22bitDMA ? STEP1_22_BIT : 0x0));
                 break;
            case InitializationStep::Step2:
                 timeout.wait_us(500); 
                 DEBUG("Transition to Init state S2.");
                  Update the SA read value for step 2:
                  S2 is set, qunibus port type (0),  SA bits 15-8 written
                  by the host in step 1.
                 Interrupt(STEP2 | ((_step1Value >> 8) & 0xff));
                 break;
            case InitializationStep::Step3:
                 timeout.wait_us(500); 
                 DEBUG("Transition to Init state S3.");
                  Update the SA read value for step 3:
                  S3 set, plus SA bits 7-0 written by the host in step 1.
                 Interrupt(STEP3 | (_step1Value & 0xff));
                 break;
            case InitializationStep::Step4:
                 timeout.wait_us(100);
                  Clear communications area, set SA   
                 DEBUG("Clearing comm area at 0x%x. Purge header: %d", _ringBase, _purgeInterruptEnable);
                 DEBUG("resp 0x%x comm 0x%x", _responseRingLength, _commandRingLength);
                 {
                     int headerSize = _purgeInterruptEnable ? 8 : 4;
                     for(uint32_t i = 0; 
                         i < (_responseRingLength + _commandRingLength) * sizeof(Descriptor) + headerSize;
                         i += 2)
                     {
                         DMAWriteWord(_ringBase + i - headerSize, 0x0);
                     }
                 }
                  Set the ownership bit on all descriptors in the response ring
                  to indicate that the port owns them.
                 Descriptor blankDescriptor;
                 blankDescriptor.Word0.Word0 = 0;
                 blankDescriptor.Word1.Word1 = 0;
                 blankDescriptor.Word1.Fields.Ownership = 1;
                 for(uint32_t i = 0; i < _responseRingLength; i++)
                 {
                     DMAWrite(
                         GetResponseDescriptorAddress(i),
                         sizeof(Descriptor),
                         reinterpret_cast<uint8_t*>(&blankDescriptor));
                 }  
                 DEBUG("Transition to Init state S4, comm area initialized.");
                  Update the SA read value for step 4:
                  Bits 7-0 indicating our control microcode version.
                 Interrupt(STEP4 | (_controllerType == UDA50 ? UDA50_ID : RQDX3_ID)); 
                 break;
            case InitializationStep::Complete:
                 DEBUG("Initialization complete.");
                 break;
        }
    }
}
void uda_c :: worker ( unsigned instance ) { UNUSED ( instance ) ; worker_init_realtime_priority ( rt_device ) ; timeout_c timeout ; while ( ! workers_terminate ) { pthread_mutex_lock ( & on_after_register_access_mutex ) ; while ( ! _next_step ) { pthread_cond_wait ( & on_after_register_access_cond , & on_after_register_access_mutex ) ; } _next_step = false ; pthread_mutex_unlock ( & on_after_register_access_mutex ) ; switch ( _initStep ) { case InitializationStep :: Uninitialized : DEBUG ( " " ) ; update_SA ( 0x0 ) ; Reset ( ) ; StateTransition ( InitializationStep :: Step1 ) ; break ; case InitializationStep :: Step1 : timeout . wait_us ( 500 ) ; DEBUG ( " " ) ; DEBUG ( " " , _22bitDMA ) ; update_SA ( STEP1 | ( _22bitDMA ? STEP1_22_BIT : 0x0 ) ) ; break ; case InitializationStep :: Step2 : timeout . wait_us ( 500 ) ; DEBUG ( " " ) ; Interrupt ( STEP2 | ( ( _step1Value >> 8 ) & 0xff ) ) ; break ; case InitializationStep :: Step3 : timeout . wait_us ( 500 ) ; DEBUG ( " " ) ; Interrupt ( STEP3 | ( _step1Value & 0xff ) ) ; break ; case InitializationStep :: Step4 : timeout . wait_us ( 100 ) ; DEBUG ( " " , _ringBase , _purgeInterruptEnable ) ; DEBUG ( " " , _responseRingLength , _commandRingLength ) ; { int headerSize = _purgeInterruptEnable ? 8 : 4 ; for ( uint32_t i = 0 ; i < ( _responseRingLength + _commandRingLength ) * sizeof ( Descriptor ) + headerSize ; i += 2 ) { DMAWriteWord ( _ringBase + i - headerSize , 0x0 ) ; } } Descriptor blankDescriptor ; blankDescriptor . Word0 . Word0 = 0 ; blankDescriptor . Word1 . Word1 = 0 ; blankDescriptor . Word1 . Fields . Ownership = 1 ; for ( uint32_t i = 0 ; i < _responseRingLength ; i ++ ) { DMAWrite ( GetResponseDescriptorAddress ( i ) , sizeof ( Descriptor ) , reinterpret_cast < uint8_t * > ( & blankDescriptor ) ) ; } DEBUG ( " " ) ; Interrupt ( STEP4 | ( _controllerType == UDA50 ? UDA50_ID : RQDX3_ID ) ) ; break ; case InitializationStep :: Complete : DEBUG ( " " ) ; break ; } } }
worker():
Implements the initialization state machine.
worker () : Implements the initialization state machine .
// only one // // Wait to be awoken. // // SA should already be zero but we'll be extra sure here. // Reset the controller: This may take some time as we must // wait for the MSCP server to wrap up its current workitem. // // S1 is set, all other bits zero.  This indicates that we // support a host-settable interrupt vector, that we do not // implement enhanced diagnostics, and that no errors have // occurred. // // Update the SA read value for step 2: // S2 is set, qunibus port type (0),  SA bits 15-8 written // by the host in step 1. // Update the SA read value for step 3: // S3 set, plus SA bits 7-0 written by the host in step 1. // Clear communications area, set SA    // // Set the ownership bit on all descriptors in the response ring // to indicate that the port owns them. // // Update the SA read value for step 4: // Bits 7-0 indicating our control microcode version.