?? diti.c
字號:
cleanup(chancfg);
return;
}
StringCopy(sema4_name, IOCTL_NAME);
sema4_name[3] = minor + '0';
if (error = sm_create(sema4_name, 0, SM_FIFO,
&chancfg->ctl_id))
{
parms->err = TERM_SEM;
parms->out_retval = error;
cleanup(chancfg);
return;
}
chancfg->dflags |= OPENED;
/*---------------------------------------------------------------------*/
/* Get a mblock to use for echo and delete. */
/*---------------------------------------------------------------------*/
if(!(chancfg->echo_mblk = gs_allocb(3, 0)))
{
parms->err = TERM_NBUFF;
cleanup(chancfg);
return;
}
chancfg->echo_rwprt = chancfg->echo_mblk->b_rptr;
/*---------------------------------------------------------------------*/
/* Set channel active RTS CTS */
/*---------------------------------------------------------------------*/
p = doctl((Lid )chancfg->lid, SIOCSACTIVATE, (void *)0, parms);
if((p != SIOCOK) && (parms->err == SIOCCFGNOTSUPPORTED))
parms->err = SIOCOK;
else
{
/*---------------------------------------------------------------------*/
/* Wait for cd */
/*---------------------------------------------------------------------*/
if(sm_p(chancfg->ctl_id, SM_WAIT, FOREVER))
{
parms->err = TERM_SEM;
cleanup(chancfg);
gs_freemsg(chancfg->echo_mblk);
chancfg->dflags &= ~OPENED;
return;
}
}
chancfg->dflags |= CONNECTED;
}
/***********************************************************************/
/* TermRead: Read from a channel */
/* */
/* INPUTS: struct ioparms */
/* ioparms->in_iopb points to a TermIO type */
/* ioparms->in_dev device number */
/* TermIO->buffp points to buffer to read into */
/* TermIO->length length of buffer */
/* */
/* OUTPUTS: ioparms->out_retval number of characters read */
/* ioparms->err error code or 0 if OK */
/* ioparms->used 1 */
/* */
/* RETURNS: */
/* TERM_NINIT driver not initialized */
/* TERM_NOPEN minor device has not been opened */
/* TERM_MINOR Invalid minor device */
/* TERM_BRKINT Terminated by a break character */
/* TERM_DCDINT Terminated by loss of DCD */
/* TERM_RXERR data receive error */
/* TERM_SEM Semaphore error */
/* TERM_QUE que error */
/* TERM_ROPER redirect operation error */
/* */
/***********************************************************************/
void TermRead (struct ioparms *parms)
{
ChanCfg *chancfg;
TermIO *conio = (TermIO *) parms->in_iopb;
mblk_t *mblk, *echo_mblk, *can_mblk=NULL;
/* =NULL, -- chg by szg for restraining warning*/
unsigned short minor;
unsigned long b_flags, wait, length, msg[4], error, timeout_ticks;
unsigned char *buffp, character;
unsigned short c_iflag, c_oflag;
static unsigned long read_access_tid;
unsigned long ret;
unsigned long oldprio, imask;
unsigned long date, time, ticks, start_ticks, vtime;
int characters_received;
/*---------------------------------------------------------------------*/
/* Set elements of the ioparms structure to their default values. */
/* used - will tell pSOS we're using stack interface */
/* out_retval - is used to pass additional error information to the */
/* user. */
/* err - will contain an error code (0 for success) */
/*---------------------------------------------------------------------*/
parms->used = 1;
parms->out_retval = 0;
parms->err = 0;
/*---------------------------------------------------------------------*/
/* Check to see if the driver has been initiatized. */
/*---------------------------------------------------------------------*/
if (!Term_Init_Done)
{
parms->err = TERM_NINIT;
return;
}
/*---------------------------------------------------------------------*/
/* Check to see if the minor device ic in range. */
/*---------------------------------------------------------------------*/
if((minor = MINOR(parms->in_dev)) > BSP_SERIAL)
{
parms->err = TERM_MINOR;
return;
}
/*---------------------------------------------------------------------*/
/* Check to see if the minor device is 0 (default console). If so */
/* set the minor device to the actual channel being used as the */
/* system console. */
/*---------------------------------------------------------------------*/
if(minor == 0)
minor = SysConsole;
chancfg = &DChanCfg[minor];
/*---------------------------------------------------------------------*/
/* Check to see if minor device has been opened. */
/*---------------------------------------------------------------------*/
if(!(chancfg->dflags & OPENED))
{
parms->err = TERM_NOPEN;
return;
}
/*---------------------------------------------------------------------*/
/* If count is zero return now on error */
/*---------------------------------------------------------------------*/
if (!(length = conio->length))
return;
/*---------------------------------------------------------------------*/
/* Get the semaphore which controls access to the device. */
/* To avoid the problem of a task being deleted while in this section */
/* of code and no other task being able to get in after that the */
/* semaphore is programmed to time out. At each time out a check */
/* will be made to see if the task that currently has this section */
/* of code is still alive. If it is not, sm_v will be called to clean */
/* up the semphore. */
/*---------------------------------------------------------------------*/
while (ret = sm_p(chancfg->rda_id, SM_WAIT,
(anchor->psosct->kc_ticks2sec/2)))
{
if (ret == ERR_TIMEOUT)
{
/*-------------------------------------------------------------*/
/* Check to see if the task that is currently blocking access */
/* is still running. */
/*-------------------------------------------------------------*/
if(ret = t_setpri(read_access_tid, 0, &oldprio))
{
if(ret == ERR_OBJDEL)
{
/*-----------------------------------------------------*/
/* Task that is blocking access has been deleted. */
/* Clean up access semaphore. */
/*-----------------------------------------------------*/
sm_v(chancfg->rda_id);
/*-----------------------------------------------------*/
/* Go back and try again. */
/*-----------------------------------------------------*/
continue;
}
else
{
/*-----------------------------------------------------*/
/* Some other error has happened just return. */
/*-----------------------------------------------------*/
parms->err = TERM_SEM;
return;
}
}
else
/*---------------------------------------------------------*/
/* Valid task still waiting in this section go back and */
/* wait some more. */
/*---------------------------------------------------------*/
continue;
}
else
{
parms->err = TERM_SEM;
return;
}
}
/*---------------------------------------------------------------------*/
/* Save off the tasks ID to be used if task is deleted */
/*---------------------------------------------------------------------*/
t_ident((char *)0, 0, &read_access_tid);
/*---------------------------------------------------------------------*/
/* Check to see if any current mblk from canonical queue available. If */
/* not, check to see if any mblks available in the canonical queue. If */
/* available, copy the characters from the mblk to user buffer until */
/* there are any characters in the canonical queue or until the read */
/* count is satisfied. If no mblk available in the canonical queue, */
/* proceed on to read mblks from the receive queue, process character */
/* if needed and then copy to user buffer (if in non canonical mode) or*/
/* to canonical queue (if in canonical mode). */
/*---------------------------------------------------------------------*/
mblk = 0;
if (chancfg->cnmblk)
mblk = chancfg->cnmblk;
else
if (q_receive(chancfg->can_id, Q_NOWAIT, 0, msg) == 0)
mblk = (mblk_t *)msg[0];
if (mblk)
{
buffp = conio->buffp;
while (length)
{
*buffp++ = *mblk->b_rptr++;
length--;
if (mblk->b_rptr >= mblk->b_wptr)
{
gs_freemsg(mblk);
if (length)
{
if (q_receive(chancfg->can_id, Q_NOWAIT, 0, msg) == 0)
mblk = (mblk_t *)msg[0];
else
break;
}
}
} /* while */
if ((mblk->b_rptr < mblk->b_wptr) &&
((*mblk->b_rptr == chancfg->termio.c_cc[VEOL]) ||
(*mblk->b_rptr == chancfg->termio.c_cc[VEOF])))
mblk->b_rptr++;
if (mblk->b_rptr < mblk->b_wptr)
chancfg->cnmblk = mblk;
else
chancfg->cnmblk = 0;
parms->out_retval = conio->length - length;
sm_v(chancfg->rda_id);
return;
}
/*---------------------------------------------------------------------*/
/* Set the characters_received for VMIN VTIME processing */
/*---------------------------------------------------------------------*/
characters_received = 0;
if (chancfg->termio.c_lflag & ICANON)
{
can_mblk = gs_allocb((int)128, 0);
if (can_mblk == NULL)
{
parms->err = TERM_NBUFF;
sm_v(chancfg->rda_id);
return;
}
buffp = can_mblk->b_wptr;
}
else
buffp = conio->buffp;
/*---------------------------------------------------------------------*/
/* The following variables are set to make lint not complain. */
/*---------------------------------------------------------------------*/
timeout_ticks = 0;
start_ticks = 0;
vtime = 0;
/*---------------------------------------------------------------------*/
/* Fill the callers buffer until length is reached or a error is found */
/* or a control character is found. */
/*---------------------------------------------------------------------*/
while(1)
{
if (!(chancfg->termio.c_lflag & ICANON) && (length == 0))
break;
/*-----------------------------------------------------------------*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -