📄 diti.c
字号:
if(DChanCfg[i].dflags & OPENED && DChanCfg[i].lid)
while (DChanCfg[i].rqhead)
{
tmblk = DChanCfg[i].rqhead;
imask = splx(MAX_ILEV);
DChanCfg[i].rqhead = tmblk->b_next;
splx(imask);
gs_freemsg(tmblk);
}
/*-----------------------------------------------------------------*/
/* If this is a re-init free any echo mblk's that were allocated. */
/*-----------------------------------------------------------------*/
if (DChanCfg[i].echo_mblk)
gs_freemsg(DChanCfg[i].echo_mblk);
}
/*---------------------------------------------------------------------*/
/* Clear DChanCfg structures */
/*---------------------------------------------------------------------*/
bzero(DChanCfg, (sizeof(ChanCfg) * (BSP_SERIAL + 1)));
Term_Init_Done = 1;
}
/***********************************************************************/
/* TermOpen: open a serial port. */
/* */
/* INPUTS: struct ioparms *parms used to return errors */
/* */
/* RETURNS: void */
/* */
/* The following error codes are returned in ioparms->err: */
/* */
/* TERM_MINOR Invalid minor device */
/* TERM_NINIT Driver no initialized */
/* TERM_AOPEN Channel already open */
/* */
/* In the case of TERM_SEM ioparms->out_retval will contain the */
/* semaphore error code. */
/* */
/***********************************************************************/
void TermOpen(struct ioparms *parms)
{
ChannelCfg channelcfg;
unsigned short minor;
char sema4_name[6];
unsigned long error;
ChanCfg *chancfg;
int p, i;
/*---------------------------------------------------------------------*/
/* SysBaud is the default baudrate set in sysinit.c */
/*---------------------------------------------------------------------*/
extern int SysBaud;
UCHAR defaultbaud;
/*---------------------------------------------------------------------*/
/* 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 initialized. */
/*---------------------------------------------------------------------*/
if (!Term_Init_Done)
{
parms->err = TERM_NINIT;
return;
}
/*---------------------------------------------------------------------*/
/* Check to see if the minor device is in a valid range. */
/* When using SC_AUTOINIT this will be zero, so skip the whole thing. */
/*---------------------------------------------------------------------*/
if((minor = MINOR(parms->in_dev)) < 1)
return;
/*---------------------------------------------------------------------*/
/* Check to see if the minor device is in range. */
/*---------------------------------------------------------------------*/
if(minor > BSP_SERIAL)
{
parms->err = TERM_MINOR;
return;
}
/*---------------------------------------------------------------------*/
/* Keep track of opens so close will know when to actually close */
/* channel. */
/*---------------------------------------------------------------------*/
DChanCfg[minor].num_open++;
/*---------------------------------------------------------------------*/
/* Check to see if minor device is already opened. */
/*---------------------------------------------------------------------*/
if(DChanCfg[minor].dflags & OPENED)
{
/*-----------------------------------------------------------------*/
/* Minor device already open. */
/*-----------------------------------------------------------------*/
return;
}
/*---------------------------------------------------------------------*/
/* Set up configuration structure that will be passed to DISI */
/* interface. */
/* NOTE: ECHO is removed from Flags before it is copied to the lower */
/* level code because it has a different meaning to the lower level */
/* code. This driver will do its own echo. */
/*---------------------------------------------------------------------*/
bzero(&channelcfg, sizeof(ChannelCfg));
channelcfg.Mode = SIOCASYNC;
channelcfg.Cfg.Uart.CharSize = SCS8;
channelcfg.Cfg.Uart.Flags = SBRKINT | SWFC | CANON;
channelcfg.Cfg.Uart.LineD[0].LChar = EOT;
channelcfg.Cfg.Uart.LineD[0].LFlags = 0;
channelcfg.Cfg.Uart.LineD[1].LChar = NL;
channelcfg.Cfg.Uart.LineD[1].LFlags = 0;
channelcfg.Cfg.Uart.LineD[2].LChar = CR;
channelcfg.Cfg.Uart.LineD[2].LFlags = ENDOFTABLE;
channelcfg.Cfg.Uart.XOnCharacter = XON;
channelcfg.Cfg.Uart.XOffCharacter = XOFF;
channelcfg.Cfg.Uart.MinChar = 1;
channelcfg.Cfg.Uart.MaxTime = 3;
channelcfg.RBuffSize = RBUFFSIZE;
channelcfg.NRBuffs = 1;
channelcfg.OutQLen = 4;
channelcfg.Baud = SysBaud;
channelcfg.LineMode = FULLD;
channelcfg.dataind = term_dataind;
channelcfg.expind = term_expind;
channelcfg.datacnf = term_datacnf;
channelcfg.ctlcnf = term_ctlcnf;
channelcfg.allocb = gs_allocb;
channelcfg.freemsg = gs_freemsg;
channelcfg.esballoc = gs_esballoc;
channelcfg.uid = (void *)&DChanCfg[minor];
/*---------------------------------------------------------------------*/
/* Call the DISI interface open */
/*---------------------------------------------------------------------*/
if(error = SerialOpen((ULONG)(minor - 1), (ChannelCfg *)&channelcfg,
(Lid )&DChanCfg[minor].lid,
(unsigned long *)&DChanCfg[minor].hdwflags))
{
/*-----------------------------------------------------------------*/
/* Return error code. */
/*-----------------------------------------------------------------*/
switch (error)
{
case SIOCAOPEN:
/*---------------------------------------------------------*/
/* The Channel has already been opened by another driver! */
/*---------------------------------------------------------*/
parms->err = TERM_ADOPEN;
return;
case SIOCBADCHANNELNUM:
/*---------------------------------------------------------*/
/* Even though the minor number is in range it is not a */
/* valid channel for this hardware. */
/*---------------------------------------------------------*/
parms->err = TERM_MINOR;
return;
case SIOCCFGNOTSUPPORTED:
/*---------------------------------------------------------*/
/* Hardware cannot be configured by the DISI as given. */
/*---------------------------------------------------------*/
parms->err = TERM_CFGHSUP;
return;
case SIOCBADBAUD:
/*---------------------------------------------------------*/
/* Baud rate not supported by hardware. */
/*---------------------------------------------------------*/
parms->err = TERM_BAUD;
return;
case SIOCBADMINCHAR:
/*---------------------------------------------------------*/
/* This error should have been caught above so something */
/* is corrupted in the lower driver. */
/*---------------------------------------------------------*/
parms->err = TERM_LDERR;
return;
case SIOCNOTINIT:
/*---------------------------------------------------------*/
/* This error shows that the lower driver thinks it is */
/* has not been initialized. Since tests made above */
/* show otherwise the driver is out of sync. */
/*---------------------------------------------------------*/
parms->err = TERM_OUTSYNC;
return;
}
}
/*---------------------------------------------------------------------*/
/* Get the address of the drivers ChanCfg for this minor device */
/*---------------------------------------------------------------------*/
chancfg = &DChanCfg[minor];
/*---------------------------------------------------------------------*/
/* Save the minor device configuration */
/*---------------------------------------------------------------------*/
chancfg->termio.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
chancfg->termio.c_oflag = OPOST | ONLCR;
for (i = 1; i < BAUD_TABLE_SIZE; i++)
if(baud_table[i] == SysBaud)
break;
if(i != BAUD_TABLE_SIZE)
defaultbaud = (i & CBAUD);
else
defaultbaud = B9600;
chancfg->termio.c_cflag = defaultbaud | CS8 | CREAD;
chancfg->termio.c_lflag = ICANON | ECHO;
chancfg->termio.c_cc[VERASE] = BS;
chancfg->termio.c_cc[VEOF] = EOT;
chancfg->termio.c_cc[VEOL] = NL;
chancfg->termio.c_cc[VSTART] = XON;
chancfg->termio.c_cc[VSTOP] = XOFF;
/*---------------------------------------------------------------------*/
/* NOTE: error returns after this could leave driver in HALF OPENED */
/* state. cleanup must be called to clear all references to channel */
/*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*/
/* Create semaphores to control task access to the read and write */
/* drivers and for signaling the end of rcv and xmit operations. */
/*---------------------------------------------------------------------*/
StringCopy(sema4_name, READ_NAME);
sema4_name[3] = minor + '0';
if (error = sm_create(sema4_name, 1, SM_FIFO,
&chancfg->rda_id))
{
parms->err = TERM_SEM;
parms->out_retval = error;
cleanup(chancfg);
return;
}
StringCopy(sema4_name, WRITE_NAME);
sema4_name[3] = minor + '0';
if (error = sm_create(sema4_name, 1, SM_FIFO,
&chancfg->wra_id))
{
parms->err = TERM_SEM;
parms->out_retval = error;
cleanup(chancfg);
return;
}
StringCopy(sema4_name, RXQUE_NAME);
sema4_name[3] = minor + '0';
if (error = q_create(sema4_name, 0, Q_FIFO | Q_SYSBUF | Q_NOLIMIT,
&chancfg->rxq_id))
{
parms->err = TERM_QUE;
parms->out_retval = error;
cleanup(chancfg);
return;
}
StringCopy(sema4_name, CANQUE_NAME);
sema4_name[3] = minor + '0';
if (error = q_create(sema4_name, 0, Q_FIFO | Q_SYSBUF | Q_NOLIMIT,
&chancfg->can_id))
{
parms->err = TERM_QUE;
parms->out_retval = error;
cleanup(chancfg);
return;
}
StringCopy(sema4_name, TXCOMP_NAME);
sema4_name[3] = minor + '0';
if (error = sm_create(sema4_name, 0, SM_FIFO,
&chancfg->txc_id))
{
parms->err = TERM_SEM;
parms->out_retval = error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -