iplleofunc.c 6.94 KB
/*
 *  F i l e N a m e  :  i p l l e o f u n c . c
 *
 ****************************************************************************
 *                   (C) Copyright ALPS Electric Co., Ltd. 1995-1996
 ****************************************************************************
 *  Version
 *
 *  ver     Data
 *  ----  --------
 *  1.08  '96-11-05  Add leoIPLReset(), leoIPLClr_queue() .
 *  1.07  '96-10-01  Change LeoIPLdma_que_buf size (1->2) .
 *  1.06  '96-09-28  Delete leoIPLDelete() routine .
 *  1.05  '96-08-07  Change function name.(leoIPLClr_thread() -> leoIPLDelete() )
 *  1.04  '96-07-25  Move ram initialize to iplleocmdex.c  .
 *                   Change interruptThread Priority (intpre -> OS_PRIORITY_PIMGR).
 *  1.03  '96-06-17  Add leoIPLClr_thread() routine .
 *  1.02  '96-02-27  Rename iplcom.c to iplleofunc.c .
 *  1.01  '96-02-03  Debug.
 *  1.00  '95-12-20  Initial revision .
 ****************************************************************************
*/
#include "os.h"

#include <ultra64.h>
#include "leodefine.h"
#include "leodrive.h"
#include "iplleomacro.h"
#include "leoappli.h"

/**************************************
*  PROTOTYPE DEFINITION
**************************************/
void leoIPLInitialize(OSPri compri, OSPri intpri);
void leoIPLCommand(void *cmd_blk_addr);
void leoIPLReset(void);
void leoIPLClr_queue(void);

/**************************************
*  EXTERNALY DEFINITION FUNCTIONS
**************************************/
extern  void leoiplMain(void *arg);
extern  void leoiplInterrupt(void *arg);

/**************************************
*  EXTERNALY DEFINITION RAM LOCATIONS
**************************************/
extern  OSThread LeoIPLcommandThread;
extern  OSThread LeoIPLinterruptThread;
extern  u64      LeoIPLcommandThreadStack[LEO_STACKSIZE/8];
extern  u64      LeoIPLinterruptThreadStack[LEO_STACKSIZE/8];

extern OSMesgQueue LeoIPLcommand_que;
extern OSMesgQueue LeoIPLevent_que;
extern OSMesgQueue LeoIPLcontrol_que;
extern OSMesgQueue LeoIPLblock_que;
extern OSMesgQueue LeoIPLdma_que;
extern OSMesg LeoIPLcommand_que_buf[CMD_BLK_Q_SIZE];
extern OSMesg LeoIPLevent_que_buf;
extern OSMesg LeoIPLcontrol_que_buf;
extern OSMesg LeoIPLblock_que_buf;
extern OSMesg LeoIPLdma_que_buf[DMA_Q_SIZE];

extern u8  LeoIPLdrive_flag;
extern volatile u8  LeoIPLclr_que_flag;

extern OSPiHandle *LeoIPLPiInfo;

#define command_block   ((LEOCmdHeader *)cmd_blk_addr)

/* ==========================================================================
* Function : leoIPLInitialize
* --------------------------------------------------------------------------
* Description : Initialeze ipl read routine
* --------------------------------------------------------------------------
* IN            : non
* 出力変数      : non
* 引数          : compri, intpri
* 戻り値        : 無し
* ==========================================================================
*/
void leoIPLInitialize(OSPri compri, OSPri intpri)
{
    /* Create queue    */
    osCreateMesgQueue(IPLCOMMAND_QUE, &LeoIPLcommand_que_buf[0], CMD_BLK_Q_SIZE);
    osCreateMesgQueue(IPLCONTROL_QUE, &LeoIPLcontrol_que_buf, CONTROL_Q_SIZE);
    osCreateMesgQueue(IPLEVENT_QUE, &LeoIPLevent_que_buf, EVENT_Q_SIZE);
    osCreateMesgQueue(IPLDMA_QUE, &LeoIPLdma_que_buf[0], DMA_Q_SIZE);
    osCreateMesgQueue(IPLBLOCK_QUE, &LeoIPLblock_que_buf, BLOCK_Q_SIZE);

    /* Create command thread and start  */
    osCreateThread(&LeoIPLcommandThread, 1, leoiplMain, (void *)0,
        (void *)(LeoIPLcommandThreadStack + LeoIPL_STACKSIZE/8), compri);
    osStartThread(&LeoIPLcommandThread);
    /* Create interrut handling thread and start  */
    osCreateThread(&LeoIPLinterruptThread, 1, leoiplInterrupt, (void *)0,
        (void *)(LeoIPLinterruptThreadStack + LeoIPL_STACKSIZE/8), OS_PRIORITY_PIMGR);
    osStartThread(&LeoIPLinterruptThread);

    /* Set interrupt to event-que */
    osSetEventMesg(OS_EVENT_CART, IPLEVENT_QUE, MES_INTERRUPT);

    /* Setup block queue  */
    osSendMesg(IPLBLOCK_QUE, MES_NONE, OS_MESG_BLOCK);

}

/*===========================================================================
* Function  :  leoIPLCommand(cmd_blk_addr)
* ---------------------------------------------------------------------------
* Description : Receive command from application and set in commnad queue.
* IN  : non
* OUT : non
* ARG : cmd_blk_addr .. top address of commnad block
* RET : non
* =========================================================================*/
void leoIPLCommand(void *cmd_blk_addr)
{
    (void)osRecvMesg(IPLBLOCK_QUE, NULL, OS_MESG_BLOCK);   /* block que */

    /* Init sense code and status in command block  */
    command_block->status = LEO_STATUS_BUSY;
    command_block->sense  = LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION;

    if (osSendMesg(IPLCOMMAND_QUE, cmd_blk_addr, OS_MESG_NOBLOCK))
    {
        /* Error if que full   */
        command_block->sense  = LEO_SENSE_QUEUE_FULL;
        command_block->status = LEO_STATUS_CHECK_CONDITION;
    }

    osSendMesg(IPLBLOCK_QUE, MES_NONE, OS_MESG_BLOCK);  /* block que */
}

/* ==========================================================================
* Function : leoIPLReset
* --------------------------------------------------------------------------
* Description : Block new command , clear queued command and reset drive.
* --------------------------------------------------------------------------
* IN    : non
* OUT   : non
* ARG   : non
* RET   : non
* ==========================================================================
*/
static const u8 zero[1]={0};
void leoIPLReset(void)
{
    /* Block new command queing */
    (void)osRecvMesg(IPLBLOCK_QUE, NULL, OS_MESG_BLOCK); 

    /* Clear queued command */
    leoiplSet_clr_que_flag();
    leoIPLClr_queue();
    leoiplClr_clr_que_flag();

    (void)osRecvMesg(IPLEVENT_QUE, NULL, OS_MESG_NOBLOCK);
    (void)osSendMesg(IPLEVENT_QUE, (OSMesg)MES_NMI_RESET, OS_MESG_BLOCK);
    (void)osSendMesg(IPLCOMMAND_QUE, (OSMesg)zero , OS_MESG_NOBLOCK);
}

/* ==========================================================================
* Function : leoIPLClear_queue
* --------------------------------------------------------------------------
* Description : Crear queued command and set status STOP.
*               Post que is enable.
* --------------------------------------------------------------------------
* IN    : non
* OUT   : non
* ARG   : non
* RET   : non
* ==========================================================================
*/
void leoIPLClr_queue(void)
{
    OSMesg temp_command;

    /* Clear queued command */
    while (!osRecvMesg(IPLCOMMAND_QUE, &temp_command, OS_MESG_NOBLOCK))
    {
        ((LEOCmdHeader *)temp_command)->sense  = LEO_SENSE_COMMAND_TERMINATED;
        ((LEOCmdHeader *)temp_command)->status = LEO_STATUS_CHECK_CONDITION;
        if (((LEOCmdHeader *)temp_command)->control & LEO_CONTROL_POST)
        {
            /* send post message */
            osSendMesg(((LEOCmdHeader *)temp_command)->post,
                                   (OSMesg)LEO_SENSE_COMMAND_TERMINATED, OS_MESG_BLOCK);
        }
    }
}