/**  To Unregister the ISRs with the underlying OS, if previously registered. */
static void unregisterEdma3Interrupts (void)
{
#if 0 //wj
  unsigned int intState;
  unsigned int numTc = 0;
  
  /* Disabling the global interrupts */
  intState = HWI_disable();
  
  /* Disable the Xfer Completion Event Interrupt */
  ECM_disableEvent(ccXferCompInt);
  
  /* Disable the CC Error Event Interrupt */
  ECM_disableEvent(ccErrorInt);
  
  /* Enable the TC Error Event Interrupt, according to the number of TCs. */
  while (numTc < numEdma3Tc)
  {
    ECM_disableEvent(tcErrorInt[numTc]);
    numTc++;
  }
  
  /* Restore interrupts */
  HWI_restore(intState);
#endif
}
/*
 *  ======== edma3OsProtectEntry ========
 *  OS critical section protect (Entry) function
 */
void edma3OsProtectEntry (unsigned int edma3InstanceId, int level, 
        unsigned int *intState)
{
    /* For now we ignore the instanceId */
/*      (void)edma3InstanceId;*/

    if (((level == EDMA3_OS_PROTECT_INTERRUPT)
        || (level == EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR))
        && (intState == NULL)) {
        return;
    }
    else {
        switch (level) {
            /* Disable all (global) interrupts */
            case EDMA3_OS_PROTECT_INTERRUPT :
                *intState = HWI_disable();
                break;

            /* Disable scheduler */
            case EDMA3_OS_PROTECT_SCHEDULER :
                TSK_disable();
                break;

            /* Disable scheduler */
            case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
                TSK_disable();
                break;

            /* Disable scheduler */
            case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
                TSK_disable();
                break;

            case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
                switch (*intState) {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                        /* Fall through... */
                        TSK_disable();
                        break;

                     default:
                        break;
                }
                break;

            default:
                break;
        }
    }
}
/**  To Register the ISRs with the underlying OS, if required. */
static void registerEdma3Interrupts (void)
{
#if 0 //wj
  unsigned int intState;
  ECM_Attrs ecmattrs = ECM_ATTRS;
  unsigned int numTc = 0;
  
  /* Disabling the global interrupts */
  intState = HWI_disable();
  
  /* Enable the Xfer Completion Event Interrupt */
  ecmattrs.unmask = 1u;
  ECM_dispatchPlug (ccXferCompInt, (ECM_Fxn)(&lisrEdma3ComplHandler0),
    &ecmattrs);
  ECM_enableEvent(ccXferCompInt);
  
  /* Enable the CC Error Event Interrupt */
  ecmattrs.unmask = 1u;
  ECM_dispatchPlug(ccErrorInt, (ECM_Fxn)(&lisrEdma3CCErrHandler0), &ecmattrs);
  ECM_enableEvent(ccErrorInt);
  
  /* Enable the TC Error Event Interrupt, according to the number of TCs. */
  while (numTc < numEdma3Tc)
  {
    ecmattrs.unmask = 1u;
    ECM_dispatchPlug (tcErrorInt[numTc],
      (ECM_Fxn)(ptrEdma3TcIsrHandler[numTc]),
      &ecmattrs);
    ECM_enableEvent(tcErrorInt[numTc]);
    numTc++;
  }
  
  
  /**
  * Enabling the HWI_ID.
  * EDMA3 interrupts (transfer completion, CC error etc.)
  * correspond to different ECM events (SoC specific). These ECM events come
  * under ECM block XXX (handling those specific ECM events). Normally, block
  * 0 handles events 4-31 (events 0-3 are reserved), block 1 handles events
  * 32-63 and so on. This ECM block XXX (or interrupt selection number XXX)
  * is mapped to a specific HWI_INT YYY in the tcf file. So to enable this
  * mapped HWI_INT YYY, one should use the corresponding bitmask in the
  * API C64_enableIER(), in which the YYY bit is SET.
  */
  C64_enableIER(EDMA3_HWI_BITMASK);
  
  /* Restore interrupts */
  HWI_restore(intState);
#endif
}
Ejemplo n.º 4
0
/*
 * DEV_deleteDevice deletes device(DEV_Device) entry in the OBJ table
 * if device by that name exist in the system.
 * This API is not reentrant
 */
Int DEV_deleteDevice (String name)
{
    DEV_TableElem *objDev;
    DEV_Device *entry;
    IOM_Fxns *iomfxns;
    Int status = SYS_OK;
    Uns key;

    /* Check if device   exists in the Device table, if not return FALSE */
    DEV_find(name, &entry);
    if (entry == NULL) {
        SYS_error("DEV", SYS_ENODEV);
        return(SYS_ENODEV);
    }

    /*
     * If device to be deleted is of type IOM call mdUnBindDev with
     * interrupts disabled
     */
    if (entry->type == DEV_IOMTYPE) {
        iomfxns = (IOM_Fxns *)entry->fxns;

        key = HWI_disable();
        status = iomfxns->mdUnBindDev(entry->devp);
        HWI_restore(key);

        if (status != IOM_COMPLETED) {
            SYS_error("DEV", SYS_EBADIO);
        }
        else {
            status = SYS_OK;
        }

    }

    /* Free Device entry in the device table */
    objDev = (DEV_TableElem *)((char *)entry - sizeof(QUE_Elem));
    QUE_remove(objDev);
    MEM_free(0, objDev, sizeof(DEV_TableElem));


    return(status);
}
Ejemplo n.º 5
0
/* Perform Playback (Tx) audio algorithm processing */
void PbAudioAlgTsk(void)
{
    Int16 status;
    Int16 *pbOutBuf;
    Uint16 tempInBlk;

    while (1)
    {
        SEM_pend(&SEM_PbAudioAlg, SYS_FOREVER);

        /* Select AER output buffer */
        HWI_disable();
        pbOutBuf = ping_pong_i2sTxBuf + (!tx_buf_sel)*i2sTxBuffSz;
        HWI_enable();

        if ((usb_play_mode == TRUE) && (rdy_to_consume_asrc_output == TRUE))
        {
            /* Combine ASRC output */
            SWI_disable();
            tempInBlk = asrcOutputFifoInBlk;
            SWI_enable();
            status = combineAsrcOutput(asrcOutputFifo, 
                asrcOutputFifoBlkNumSamps, 
                tempInBlk, 
                &asrcOutputFifoOutBlk, 
                &asrcOutputFifoOutBlkSampCnt, 
                ASRC_NUM_CH_STEREO, 
                tempPbOutBuf, 
                i2sTxBuffSz>>1);
            if (status == CMBASRC_FIFO_UND)
            {
                asrcOutputFifoOutError++;
                LOG_printf(&trace, "ERROR: ASRC output FIFO UNDERFLOW");
                //LOG_printf(&trace, "%04x %d", (asrcOutputFifoInBlk<<8) | asrcOutputFifoOutBlk, asrcOutputFifoOutBlkSampCnt); // debug
            }
        }
        else if (usb_play_mode == TRUE)
void ProtocolTest3()
{
#if PROFILE_TEST_SERVICE == true
    double executionTime;
    Uint32 startTime;
#endif
    struct Packet newPacket;
    Uns interruptStatus;
    Uint16 x[100], i, j, destination;
    double executionTime = 0;
    double avgTime[9] = {0,0,0,0,0,0,0,0,0};
    double minTime[9] = {DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX};
    double maxTime[9] = {DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN};
    Uint32 startTime = 0;
    Uint32 numSamples;

    SEM_pend(&TestServiceSem,SYS_FOREVER);

    for(i = 0; i < 100; i++)
        x[i] = i;

    if(globals.protocol.address == 1)
    {
        globals.processing.sevenSegmentUpperDigit = SEVENSEG_1DASH;

        destination = (gpioDataRegisters.GPBDAT.bit.SWITCH1 << 3) + (gpioDataRegisters.GPBDAT.bit.SWITCH2 << 2) +
                      (gpioDataRegisters.GPADAT.bit.SWITCH3 << 1) + (gpioDataRegisters.GPADAT.bit.SWITCH4);

        interruptStatus = HWI_disable();
        numSamples = 0;
        for(j = 0; j < 100; j++)
        {
            startTime = timer0Registers.TIM.all;
            GenerateRoutingPath(globals.protocol.address, 1, &newPacket);
            executionTime = TimeDifference(startTime, timer0Registers.TIM.all);
            avgTime[1] = (avgTime[1] * numSamples) + executionTime;
            numSamples++;
            avgTime[1] /= numSamples;
            if(executionTime < minTime[1])
                minTime[1] = executionTime;
            else if(executionTime > maxTime[1])
                maxTime[1] = executionTime;
        }
        for(i = 3; i <= 8; i++)
        {
            numSamples = 0;
            for(j = 0; j < 100; j++)
            {
                startTime = timer0Registers.TIM.all;
                GenerateRoutingPath(globals.protocol.address, i, &newPacket);
                executionTime = TimeDifference(startTime, timer0Registers.TIM.all);
                avgTime[i] = (avgTime[i] * numSamples) + executionTime;
                numSamples++;
                avgTime[i] /= numSamples;
                if(executionTime < minTime[i])
                    minTime[i] = executionTime;
                else if(executionTime > maxTime[i])
                    maxTime[i] = executionTime;
            }
        }
        HWI_restore(interruptStatus);
        asm(" NOP");

        for(i = 0; i < 100; i++)
        {
            for(j = 0; j < 50; j++)
            {
                InitializePacket(&newPacket, PACKET_ID_UNDEFINED);

                // Create the data transfer packet
                newPacket.a.communicationType = COMM_TYPE_UNICAST;
                newPacket.transmissionInfo.destination = 7;
                newPacket.b.command = COMMAND_DATA_TRANSFER;
                newPacket.b.packetSequenceStep = SEQUENCE_DATA_TRANSFER_REQUEST_TRANSFER;

                // Set the data
                newPacket.dataBuffer = x;
                newPacket.dataBufferInfo.dataBufferLength = 10;

                SendDataPacket(&newPacket);

                InitializePacket(&newPacket, PACKET_ID_UNDEFINED);

                // Create the data transfer packet
                newPacket.a.communicationType = COMM_TYPE_UNICAST;
                newPacket.transmissionInfo.destination = 8;
                newPacket.b.command = COMMAND_DATA_TRANSFER;
                newPacket.b.packetSequenceStep = SEQUENCE_DATA_TRANSFER_REQUEST_TRANSFER;

                // Set the data
                newPacket.dataBuffer = x;
                newPacket.dataBufferInfo.dataBufferLength = 10;

                SendDataPacket(&newPacket);

                while(globals.statistics.packet.numDataTransfersSucceeded + globals.statistics.packet.numDataTransfersExpired +
                        globals.statistics.packet.numDataTransfersFailed < globals.statistics.packet.numDataTransfersSetup);

            }
            if(globals.processing.sevenSegmentUpperDigit == SEVENSEG_2DASH)
                globals.processing.sevenSegmentUpperDigit = SEVENSEG_1DASH;
            else
                globals.processing.sevenSegmentUpperDigit = SEVENSEG_2DASH;
        }
        globals.processing.sevenSegmentUpperDigit = SEVENSEG_3DASH;
    }
}
void InitializeSystem(void* parameter, Uint16 followUpItemIndex)
{

	Uns interruptStatus;
	Uint16 i, j;
	double executionTime = 0;
	double genAvgTime = 0;
	double genMinTime = DBL_MAX;
	double genMaxTime = DBL_MIN;
	double avgTime[9] = {0,0,0,0,0,0,0,0,0};
	double minTime[9] = {DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX};
	double maxTime[9] = {DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN,DBL_MIN};
	Uint32 startTime = 0;
	Uint32 numSamples;
	struct Packet newPacket;

	// Allow the system to write to the system registers
	EALLOW;

	// Set up the heartbeat
	gpioCtrlRegisters.GPBDIR.bit.HEARTBEAT = 1;
	gpioDataRegisters.GPBDAT.bit.HEARTBEAT = 1;

	// Set up the seven segment display
	gpioCtrlRegisters.GPADIR.bit.SEVENSEG_A = 1;
	gpioDataRegisters.GPADAT.bit.SEVENSEG_A = 0;
	gpioCtrlRegisters.GPADIR.bit.SEVENSEG_B = 1;
	gpioDataRegisters.GPADAT.bit.SEVENSEG_B = 0;
	gpioCtrlRegisters.GPADIR.bit.SEVENSEG_C = 1;
	gpioDataRegisters.GPADAT.bit.SEVENSEG_C = 0;
	gpioCtrlRegisters.GPADIR.bit.SEVENSEG_D = 1;
	gpioDataRegisters.GPADAT.bit.SEVENSEG_D = 0;
	gpioCtrlRegisters.GPADIR.bit.SEVENSEG_E = 1;
	gpioDataRegisters.GPADAT.bit.SEVENSEG_E = 0;
	gpioCtrlRegisters.GPADIR.bit.SEVENSEG_F = 1;
	gpioDataRegisters.GPADAT.bit.SEVENSEG_F = 0;
	gpioCtrlRegisters.GPADIR.bit.SEVENSEG_G = 1;
	gpioDataRegisters.GPADAT.bit.SEVENSEG_G = 0;
	gpioCtrlRegisters.GPADIR.bit.SEVENSEG_DIGIT = 1;
	gpioDataRegisters.GPADAT.bit.SEVENSEG_DIGIT = 1;
	
	// Set up timer 0 for use with SPI related timings
	sysCtrlRegisters.HISPCP.all = 0;				// Set the HSPCLK to run at SYSCLK
	sysCtrlRegisters.LOSPCP.bit.LSPCLK = 0; 		// Set the LSPCLK to run at SYSCLK
	timer0Registers.TCR.bit.TSS = 1;				// Stop the timer
	timer0Registers.TPR.bit.TDDR = 0;				// Do not prescale the timer
	timer0Registers.PRD.all = 0xFFFFFFFF;			// Set the period register to it's largest possible value
	timer0Registers.TCR.bit.TIE = false;			// Disable timer interrupts
	timer0Registers.TCR.bit.FREE = 0;				// Set the timer to stop when a breakpoint occrs
	timer0Registers.TCR.bit.SOFT = 0;
	timer0Registers.TCR.bit.TRB = 1;				// Load the period register
	timer0Registers.TCR.bit.TSS = 0;				// Start the timer
	
	// Set up the global SPI-related settings
	IER |= 0x20;									// Enable CPU INT6
	
	// Disallow the system to write to the system registers
	EDIS;

	interruptStatus = HWI_disable();
	numSamples = 0;
	for(j = 0; j < 1000; j++)
	{
		
		InitializeGlobalVariables();

		globals.root.availableAddresses[0].address = 1;
		globals.root.availableAddresses[0].addressTaken = true;
		globals.root.availableAddresses[1].address = 2;
		globals.root.availableAddresses[1].addressTaken = true;
		globals.root.availableAddresses[2].address = 3;
		globals.root.availableAddresses[2].addressTaken = true;
		globals.root.availableAddresses[3].address = 4;
		globals.root.availableAddresses[3].addressTaken = true;
		globals.root.availableAddresses[4].address = 5;
		globals.root.availableAddresses[4].addressTaken = true;
		globals.root.availableAddresses[5].address = 6;
		globals.root.availableAddresses[5].addressTaken = true;
		globals.root.availableAddresses[6].address = 7;
		globals.root.availableAddresses[6].addressTaken = true;
		globals.root.availableAddresses[7].address = 8;
		globals.root.availableAddresses[7].addressTaken = true;	

		globals.protocol.globalNeighborInfo[1][PORTA].nodeAddress = 2;
		globals.protocol.globalNeighborInfo[1][PORTB].nodeAddress = 3;

		globals.protocol.globalNeighborInfo[2][PORTA].nodeAddress = 1;
		globals.protocol.globalNeighborInfo[2][PORTB].nodeAddress = 4;

		globals.protocol.globalNeighborInfo[3][PORTA].nodeAddress = 1;
		globals.protocol.globalNeighborInfo[3][PORTB].nodeAddress = 4;
		globals.protocol.globalNeighborInfo[3][PORTC].nodeAddress = 5;

		globals.protocol.globalNeighborInfo[4][PORTA].nodeAddress = 2;
		globals.protocol.globalNeighborInfo[4][PORTB].nodeAddress = 3;
		globals.protocol.globalNeighborInfo[4][PORTC].nodeAddress = 6;

		globals.protocol.globalNeighborInfo[5][PORTA].nodeAddress = 3;
		globals.protocol.globalNeighborInfo[5][PORTB].nodeAddress = 6;
		globals.protocol.globalNeighborInfo[5][PORTC].nodeAddress = 7;

		globals.protocol.globalNeighborInfo[6][PORTA].nodeAddress = 4;
		globals.protocol.globalNeighborInfo[6][PORTB].nodeAddress = 5;
		globals.protocol.globalNeighborInfo[6][PORTC].nodeAddress = 8;

		globals.protocol.globalNeighborInfo[7][PORTA].nodeAddress = 5;
		globals.protocol.globalNeighborInfo[7][PORTB].nodeAddress = 8;

		globals.protocol.globalNeighborInfo[8][PORTA].nodeAddress = 6;
		globals.protocol.globalNeighborInfo[8][PORTB].nodeAddress = 7;

		startTime = timer0Registers.TIM.all;
		GenerateRoutingTree();
		executionTime = TimeDifference(startTime, timer0Registers.TIM.all);
		genAvgTime = (genAvgTime * numSamples) + executionTime;
		numSamples++;
		genAvgTime /= numSamples;
		if(executionTime < genMinTime)
			genMinTime = executionTime;
		else if(executionTime > genMaxTime)
			genMaxTime = executionTime;
	}

	for(i = 2; i <= 8; i++)
	{
		numSamples = 0;
		for(j = 0; j < 1000; j++)
		{
			startTime = timer0Registers.TIM.all;
			GenerateRoutingPath(1, i, &newPacket);
			executionTime = TimeDifference(startTime, timer0Registers.TIM.all);
			avgTime[i] = (avgTime[i] * numSamples) + executionTime;
			numSamples++;
			avgTime[i] /= numSamples;
			if(executionTime < minTime[i])
				minTime[i] = executionTime;
			else if(executionTime > maxTime[i])
				maxTime[i] = executionTime;
		}
	}
	HWI_restore(interruptStatus);
	asm(" NOP");

	// Set the seed for the random number generator
	SetRandomSeed(0x175E);

	// Set up each individual port
	SetupPort(PORTA);
	SetupPort(PORTB);
	SetupPort(PORTC);
	SetupPort(PORTD);

	// Create the direct data cleanup follow-up item
	AddFollowUpItem(&CleanupDirectData,NULL,DIRECT_DATA_CLEANUP_RATE,true);

	// Create the neighbor check follow-up item
#if defined(IS_ROOT)

#if TEST != TEST_SPI
	globals.followUpMonitor.neighborFollowUpIndex = AddFollowUpItem(&NeighborFollowUp,NULL,NEIGHBOR_FOLLOW_UP_RATE,true);
#endif
	SetSevenSegmentDisplay(SEVENSEG_BLANK);
	globals.processing.sevenSegmentLowerDigit = globals.protocol.address;

#elif defined (IS_ROUTER)

#if TEST != TEST_SPI
	globals.followUpMonitor.neighborFollowUpIndex = AddFollowUpItem(&NeighborFollowUp,NULL,NEIGHBOR_FOLLOW_UP_RATE_WITHOUT_ADDRESS,true);
#endif
	SetSevenSegmentDisplay(SEVENSEG_BLANK);

	// Register the test service
	RegisterServiceProvider(TEST_SERVICE_TAG,TEST_SERVICE_TASK_PRIORITY,&TestServiceTask,&TestServiceSem);

#endif

	

	// Let the other threads know that initialization is finished
	SEM_post(&ProcessInboundFlitsSem);
	SEM_post(&TestServiceSem);
}
/**
* \brief   EDMA3 OS Protect Entry
*
*      This function saves the current state of protection in 'intState'
*      variable passed by caller, if the protection level is
*      EDMA3_OS_PROTECT_INTERRUPT. It then applies the requested level of
*      protection.
*      For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and
*      EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,
*      and the requested interrupt is disabled.
*      For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, '*intState' specifies the
*      Transfer Controller number whose interrupt needs to be disabled.
*
* \param   level is numeric identifier of the desired degree of protection.
* \param   intState is memory location where current state of protection is
*      saved for future use while restoring it via edma3OsProtectExit() (Only
*      for EDMA3_OS_PROTECT_INTERRUPT protection level).
* \return  None
*/
void edma3OsProtectEntry (int level, unsigned int *intState)
{
#if 0  //wj
  if (((level == EDMA3_OS_PROTECT_INTERRUPT)
    || (level == EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR))
    && (intState == NULL))
  {
    return;
  }
  else
  {
    switch (level)
    {
      /* Disable all (global) interrupts */
    case EDMA3_OS_PROTECT_INTERRUPT :
      *intState = HWI_disable();
      break;
      
      /* Disable scheduler */
    case EDMA3_OS_PROTECT_SCHEDULER :
      TSK_disable();
      break;
      
      /* Disable EDMA3 transfer completion interrupt only */
    case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
      ECM_disableEvent(ccXferCompInt);
      break;
      
      /* Disable EDMA3 CC error interrupt only */
    case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
      ECM_disableEvent(ccErrorInt);
      break;
      
      /* Disable EDMA3 TC error interrupt only */
    case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
      switch (*intState)
      {
      case 0:
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
      case 7:
        /* Fall through... */
        /* Disable the corresponding interrupt */
        ECM_disableEvent(tcErrorInt[*intState]);
        break;
        
      default:
        break;
      }
      
      break;
      
      default:
        break;
    }
  }
#endif
}
Ejemplo n.º 9
0
/*
 * DEV_createDevice creates device(DEV_Device) entry in the OBJ table
 * if device by that name do not exist in the system.
 * This API is not reentrant
 */
Int DEV_createDevice (String name, Void *fxns,   Fxn initFxn,
        DEV_Attrs *attrs)
{
    DEV_TableElem *objDevHead = (DEV_TableElem*) &DEV_table;
    DEV_TableElem *objDev, *objEntry;
    DEV_Device *dptr, *entry;
    IOM_Fxns *iomfxns;
    Int status;
    Uns key;

    /*
     * Crate a device entry, if not successful return
     * SYS_EALLOC. 
     */

    objEntry = MEM_calloc(0, sizeof(DEV_TableElem), 0);

    if (objEntry == NULL) {
        return(SYS_EALLOC);
    }

    TSK_disable();


    /*
     * Check if device already exists in the Device table, if yes return
     * SYS_EINVAL
     */
    DEV_find(name, &entry);

    if (entry != NULL) {
        TSK_enable();
        MEM_free(0, objEntry, sizeof(DEV_TableElem));
        SYS_error("DEV", SYS_EINVAL);
        return(SYS_EINVAL);
    }

    /*
     * Initialize new device entry(DEV_Device) in the OBJ table with
     * the parameters passed to API
     */
    entry = &objEntry->device;
    entry->name = name;
    entry->fxns = fxns;

    if (attrs == NULL) {
        attrs = &DEV_ATTRS;
    }
    entry->devid  = attrs->devid;
    entry->params = attrs->params;
    entry->type   = attrs->type;
    entry->devp   = attrs->devp;

    /*
     * Call the Device init function if its not NULL, with interrupts
     * disabled.
     */
    if (initFxn != NULL) {
        key = HWI_disable();
        (*initFxn)();
        HWI_restore(key);
    }

    /*
     * If device created is of type IOM then call mini driver function
     * mdBindDev with interrupts disabled.
     */
    if (entry->type == DEV_IOMTYPE) {
        iomfxns = (IOM_Fxns *) entry->fxns;

        key = HWI_disable();
        status = iomfxns->mdBindDev(&entry->devp, entry->devid,
                                     entry->params);
        HWI_restore(key);

        if (status != IOM_COMPLETED) {
            
            TSK_enable();

            /* Delete the just created device entry in device table */
            MEM_free(0, objEntry, sizeof(DEV_TableElem));

            SYS_error("DEV", SYS_EBADIO);

            return(status);
        }

    }

    /*
     * Device is ready for addition into OBJ_Table. Check new device
     * name length against existing device name lengths. If length of
     * new device is greater than one in OBJ_table, mark the location
     * and insert device ahead of device whose name length is shorter
     * else add it to the end.
     *
     * This will keep all the devices sorted in descending order, which is
     * required to pass additional parameters along with device name in 
     * DEV_open()
     */

    objDev = (DEV_TableElem *)QUE_next((Ptr)objDevHead);
    while (objDev != objDevHead) {
        dptr = &objDev->device;
        if (strlen(name) > strlen(dptr->name)) {
            break;
        }
        objDev = (DEV_TableElem *)QUE_next((Ptr)objDev);
    }

    /* Insert objEntry ahead of objDev */
    QUE_insert(objDev, objEntry);

    TSK_enable();

    return(SYS_OK);
}