int enable_datapath(struct tty_struct *tty)
{
	struct cidatatty_port *cidatatty = tty->driver_data;

	if (!cidatatty)
		return 0;

	if (tty->index == PSDTTYINDEX)
		registerRxCallBack(PDP_PPP, (DataRxCallbackFunc) data_rx_ppp);
	else if (tty->index == CSDTTYINDEX)
		registerRxCallBack(CSD_RAW, (DataRxCallbackFunc) data_rx_csd);
	else if (tty->index == IMSTTYINDEX)
		registerRxCallBack(IMS_RAW, (DataRxCallbackFunc)data_rx_ims);

	return 0;
}
void PppReset(void)
{
	PppControl.isConfigReqSent = FALSE;
	PppControl.IsRxFragmented = FALSE;
	PppControl.IsEscapeFound = FALSE;
	PppControl.FlagState = HDLC_FLAG_NONE;
	pppSetLcpParams(&PppControl);
	PppControl.LastXmitId = 0;
	PppControl.ipcpRecvAck = FALSE;
	PppControl.PppState = PPP_STATE_NONE;
	PppControl.isConnectIndSent = FALSE;
	PppControl.Cid = 0xFF;
	PppControl.lcpEchoReqTimeoutCount = 0;
	PppControl.ipcpXmitParams.IpAddress = 0;

	PppControl.CPOOMDrops = 0;
	PppControl.APOOMDrops = 0;

	del_timer(&PppControl.PppTimer);
	del_timer(&PppControl.LcpEchoReqTimeoutTimer);
	registerRxCallBack(PppControl.ServiceType, NULL);

}
static int cidatatty_open(struct tty_struct *tty, struct file *file)
{
	struct cidatatty_port *cidatatty;
	int index;
	int status;
	unsigned long flags;

	F_ENTER();
	/* initialize the pointer in case something fails */
	tty->driver_data = NULL;

	/* get the serial object associated with this tty pointer */
	index = tty->index;
	/* ttycurindex = index; */
	/* PDEBUG("ttycurindex=%d\n", ttycurindex); */
	do {
		mutex_lock(&cidatatty_table[index].lock);
		cidatatty = cidatatty_table[index].data_port;
		if (!cidatatty)
			status = -ENODEV;
		else {
			spin_lock_irqsave(&cidatatty->port_lock, flags);
			/* already open? great */
			if (cidatatty->port.count) {
				status = 0;
				cidatatty->port.count++;
			/* currently opening/closing? wait */
			} else if (cidatatty->openclose) {
				status = -EBUSY;
			/* else we do the work */
			} else {
				status = -EAGAIN;
				cidatatty->openclose = true;
			}
			spin_unlock_irqrestore(&cidatatty->port_lock, flags);
		}
		mutex_unlock(&cidatatty_table[index].lock);

		switch (status) {
		default:
			/* fully handled */
			return status;
		case -EAGAIN:
			/* must do the work */
			break;
		case -EBUSY:
			/* wait for EAGAIN task to finish */
			msleep(20);
			/* REVIST could have a wait channel here, if
			 * concurrent open performance is important */
			break;
		}
	} while (status != -EAGAIN);

	/* do the real open operation */
	spin_lock_irqsave(&cidatatty->port_lock, flags);

	/* save our structure within the tty structure */
	tty->driver_data = cidatatty;

	/* jzwu1 */
	tty->flags = TTY_NO_WRITE_SPLIT | tty->flags;
	cidatatty->port.tty = tty;
	cidatatty->port.count = 0;
	cidatatty->openclose = false;
	cidatatty->port.low_latency = 1;
	status = 0;

	++cidatatty->port.count;
	if (cidatatty->port.count == 1) {
		/* this is the first time this port is opened */
		/* do any hardware initialization needed here */
		if (index == PSDTTYINDEX)
			registerRxCallBack(PDP_PPP,
					   (DataRxCallbackFunc) data_rx_ppp);
		else if (index == CSDTTYINDEX)
			registerRxCallBack(CSD_RAW,
					   (DataRxCallbackFunc) data_rx_csd);
		else if (index == IMSTTYINDEX)
			registerRxCallBack(IMS_RAW,
					   (DataRxCallbackFunc) data_rx_ims);
		else {
			cidatatty_table[index].data_port = NULL;
			spin_unlock_irqrestore(&cidatatty->port_lock, flags);
			tty_port_destroy(&cidatatty->port);
			kfree(cidatatty);
			printk(KERN_ERR "Not supported index: %d\n", index);
			return -EIO;
		}
	}
	cidatatty->writeokflag = 1;
	cidatatty->devinuse = 1;
	if (index == PSDTTYINDEX)
		cidatatty->cid = currcid_ps;
	else if (index == CSDTTYINDEX)
		cidatatty->cid = currcid_cs;
	else if (index == IMSTTYINDEX)
		cidatatty->cid = currcid_ims;

	spin_unlock_irqrestore(&cidatatty->port_lock, flags);

	F_LEAVE();
	return status;
}