⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 moxa.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	short lowwater = 512;	ofsAddr = moxa_ports[port].tableAddr;	writew(lowwater, ofsAddr + Low_water);	moxa_ports[port].breakCnt = 0;	if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||	    (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {		moxafunc(ofsAddr, FC_SetBreakIrq, 0);	} else {		writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat);	}	moxafunc(ofsAddr, FC_SetLineIrq, Magic_code);	moxafunc(ofsAddr, FC_FlushQueue, 2);	moxafunc(ofsAddr, FC_EnableCH, Magic_code);	MoxaPortLineStatus(port);}void MoxaPortDisable(int port){	void __iomem *ofsAddr = moxa_ports[port].tableAddr;	moxafunc(ofsAddr, FC_SetFlowCtl, 0);	/* disable flow control */	moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code);	writew(0, ofsAddr + HostStat);	moxafunc(ofsAddr, FC_DisableCH, Magic_code);}long MoxaPortGetMaxBaud(int port){	if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||	    (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI))		return (460800L);	else		return (921600L);}long MoxaPortSetBaud(int port, long baud){	void __iomem *ofsAddr;	long max, clock;	unsigned int val;	if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0))		return (0);	ofsAddr = moxa_ports[port].tableAddr;	if (baud > max)		baud = max;	if (max == 38400L)		clock = 614400L;	/* for 9.8304 Mhz : max. 38400 bps */	else if (max == 57600L)		clock = 691200L;	/* for 11.0592 Mhz : max. 57600 bps */	else		clock = 921600L;	/* for 14.7456 Mhz : max. 115200 bps */	val = clock / baud;	moxafunc(ofsAddr, FC_SetBaud, val);	baud = clock / val;	moxa_ports[port].curBaud = baud;	return (baud);}int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud){	void __iomem *ofsAddr;	tcflag_t cflag;	tcflag_t mode = 0;	if (moxa_ports[port].chkPort == 0 || termio == 0)		return (-1);	ofsAddr = moxa_ports[port].tableAddr;	cflag = termio->c_cflag;	/* termio->c_cflag */	mode = termio->c_cflag & CSIZE;	if (mode == CS5)		mode = MX_CS5;	else if (mode == CS6)		mode = MX_CS6;	else if (mode == CS7)		mode = MX_CS7;	else if (mode == CS8)		mode = MX_CS8;	if (termio->c_cflag & CSTOPB) {		if (mode == MX_CS5)			mode |= MX_STOP15;		else			mode |= MX_STOP2;	} else		mode |= MX_STOP1;	if (termio->c_cflag & PARENB) {		if (termio->c_cflag & PARODD)			mode |= MX_PARODD;		else			mode |= MX_PAREVEN;	} else		mode |= MX_PARNONE;	moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode);	if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||	    (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {		if (baud >= 921600L)			return (-1);	}	MoxaPortSetBaud(port, baud);	if (termio->c_iflag & (IXON | IXOFF | IXANY)) {		writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);		writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);		writeb(FC_SetXonXoff, ofsAddr + FuncCode);		moxa_wait_finish(ofsAddr);	}	return (0);}int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState){	if (!MoxaPortIsValid(port))		return (-1);	if (dtrState) {		if (moxa_ports[port].lineCtrl & DTR_ON)			*dtrState = 1;		else			*dtrState = 0;	}	if (rtsState) {		if (moxa_ports[port].lineCtrl & RTS_ON)			*rtsState = 1;		else			*rtsState = 0;	}	return (0);}void MoxaPortLineCtrl(int port, int dtr, int rts){	void __iomem *ofsAddr;	int mode;	ofsAddr = moxa_ports[port].tableAddr;	mode = 0;	if (dtr)		mode |= DTR_ON;	if (rts)		mode |= RTS_ON;	moxa_ports[port].lineCtrl = mode;	moxafunc(ofsAddr, FC_LineControl, mode);}void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany){	void __iomem *ofsAddr;	int mode;	ofsAddr = moxa_ports[port].tableAddr;	mode = 0;	if (rts)		mode |= RTS_FlowCtl;	if (cts)		mode |= CTS_FlowCtl;	if (txflow)		mode |= Tx_FlowCtl;	if (rxflow)		mode |= Rx_FlowCtl;	if (txany)		mode |= IXM_IXANY;	moxafunc(ofsAddr, FC_SetFlowCtl, mode);}int MoxaPortLineStatus(int port){	void __iomem *ofsAddr;	int val;	ofsAddr = moxa_ports[port].tableAddr;	if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||	    (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {		moxafunc(ofsAddr, FC_LineStatus, 0);		val = readw(ofsAddr + FuncArg);	} else {		val = readw(ofsAddr + FlagStat) >> 4;	}	val &= 0x0B;	if (val & 8) {		val |= 4;		if ((moxa_ports[port].DCDState & DCD_oldstate) == 0)			moxa_ports[port].DCDState = (DCD_oldstate | DCD_changed);	} else {		if (moxa_ports[port].DCDState & DCD_oldstate)			moxa_ports[port].DCDState = DCD_changed;	}	val &= 7;	return (val);}int MoxaPortDCDChange(int port){	int n;	if (moxa_ports[port].chkPort == 0)		return (0);	n = moxa_ports[port].DCDState;	moxa_ports[port].DCDState &= ~DCD_changed;	n &= DCD_changed;	return (n);}int MoxaPortDCDON(int port){	int n;	if (moxa_ports[port].chkPort == 0)		return (0);	if (moxa_ports[port].DCDState & DCD_oldstate)		n = 1;	else		n = 0;	return (n);}int MoxaPortWriteData(int port, unsigned char * buffer, int len){	int c, total, i;	ushort tail;	int cnt;	ushort head, tx_mask, spage, epage;	ushort pageno, pageofs, bufhead;	void __iomem *baseAddr, *ofsAddr, *ofs;	ofsAddr = moxa_ports[port].tableAddr;	baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem;	tx_mask = readw(ofsAddr + TX_mask);	spage = readw(ofsAddr + Page_txb);	epage = readw(ofsAddr + EndPage_txb);	tail = readw(ofsAddr + TXwptr);	head = readw(ofsAddr + TXrptr);	c = (head > tail) ? (head - tail - 1)	    : (head - tail + tx_mask);	if (c > len)		c = len;	moxaLog.txcnt[port] += c;	total = c;	if (spage == epage) {		bufhead = readw(ofsAddr + Ofs_txb);		writew(spage, baseAddr + Control_reg);		while (c > 0) {			if (head > tail)				len = head - tail - 1;			else				len = tx_mask + 1 - tail;			len = (c > len) ? len : c;			ofs = baseAddr + DynPage_addr + bufhead + tail;			for (i = 0; i < len; i++)				writeb(*buffer++, ofs + i);			tail = (tail + len) & tx_mask;			c -= len;		}		writew(tail, ofsAddr + TXwptr);	} else {		len = c;		pageno = spage + (tail >> 13);		pageofs = tail & Page_mask;		do {			cnt = Page_size - pageofs;			if (cnt > c)				cnt = c;			c -= cnt;			writeb(pageno, baseAddr + Control_reg);			ofs = baseAddr + DynPage_addr + pageofs;			for (i = 0; i < cnt; i++)				writeb(*buffer++, ofs + i);			if (c == 0) {				writew((tail + len) & tx_mask, ofsAddr + TXwptr);				break;			}			if (++pageno == epage)				pageno = spage;			pageofs = 0;		} while (1);	}	writeb(1, ofsAddr + CD180TXirq);	/* start to send */	return (total);}int MoxaPortReadData(int port, struct tty_struct *tty){	register ushort head, pageofs;	int i, count, cnt, len, total, remain;	ushort tail, rx_mask, spage, epage;	ushort pageno, bufhead;	void __iomem *baseAddr, *ofsAddr, *ofs;	ofsAddr = moxa_ports[port].tableAddr;	baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem;	head = readw(ofsAddr + RXrptr);	tail = readw(ofsAddr + RXwptr);	rx_mask = readw(ofsAddr + RX_mask);	spage = readw(ofsAddr + Page_rxb);	epage = readw(ofsAddr + EndPage_rxb);	count = (tail >= head) ? (tail - head)	    : (tail - head + rx_mask + 1);	if (count == 0)		return 0;	total = count;	remain = count - total;	moxaLog.rxcnt[port] += total;	count = total;	if (spage == epage) {		bufhead = readw(ofsAddr + Ofs_rxb);		writew(spage, baseAddr + Control_reg);		while (count > 0) {			if (tail >= head)				len = tail - head;			else				len = rx_mask + 1 - head;			len = (count > len) ? len : count;			ofs = baseAddr + DynPage_addr + bufhead + head;			for (i = 0; i < len; i++)				tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);			head = (head + len) & rx_mask;			count -= len;		}		writew(head, ofsAddr + RXrptr);	} else {		len = count;		pageno = spage + (head >> 13);		pageofs = head & Page_mask;		do {			cnt = Page_size - pageofs;			if (cnt > count)				cnt = count;			count -= cnt;			writew(pageno, baseAddr + Control_reg);			ofs = baseAddr + DynPage_addr + pageofs;			for (i = 0; i < cnt; i++)				tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);			if (count == 0) {				writew((head + len) & rx_mask, ofsAddr + RXrptr);				break;			}			if (++pageno == epage)				pageno = spage;			pageofs = 0;		} while (1);	}	if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) {		moxaLowWaterChk = 1;		moxa_ports[port].lowChkFlag = 1;	}	return (total);}int MoxaPortTxQueue(int port){	void __iomem *ofsAddr;	ushort rptr, wptr, mask;	int len;	ofsAddr = moxa_ports[port].tableAddr;	rptr = readw(ofsAddr + TXrptr);	wptr = readw(ofsAddr + TXwptr);	mask = readw(ofsAddr + TX_mask);	len = (wptr - rptr) & mask;	return (len);}int MoxaPortTxFree(int port){	void __iomem *ofsAddr;	ushort rptr, wptr, mask;	int len;	ofsAddr = moxa_ports[port].tableAddr;	rptr = readw(ofsAddr + TXrptr);	wptr = readw(ofsAddr + TXwptr);	mask = readw(ofsAddr + TX_mask);	len = mask - ((wptr - rptr) & mask);	return (len);}int MoxaPortRxQueue(int port){	void __iomem *ofsAddr;	ushort rptr, wptr, mask;	int len;	ofsAddr = moxa_ports[port].tableAddr;	rptr = readw(ofsAddr + RXrptr);	wptr = readw(ofsAddr + RXwptr);	mask = readw(ofsAddr + RX_mask);	len = (wptr - rptr) & mask;	return (len);}void MoxaPortTxDisable(int port){	void __iomem *ofsAddr;	ofsAddr = moxa_ports[port].tableAddr;	moxafunc(ofsAddr, FC_SetXoffState, Magic_code);}void MoxaPortTxEnable(int port){	void __iomem *ofsAddr;	ofsAddr = moxa_ports[port].tableAddr;	moxafunc(ofsAddr, FC_SetXonState, Magic_code);}int MoxaPortResetBrkCnt(int port){	ushort cnt;	cnt = moxa_ports[port].breakCnt;	moxa_ports[port].breakCnt = 0;	return (cnt);}void MoxaPortSendBreak(int port, int ms100){	void __iomem *ofsAddr;	ofsAddr = moxa_ports[port].tableAddr;	if (ms100) {		moxafunc(ofsAddr, FC_SendBreak, Magic_code);		msleep(ms100 * 10);	} else {		moxafunc(ofsAddr, FC_SendBreak, Magic_code);		msleep(250);	}	moxafunc(ofsAddr, FC_StopBreak, Magic_code);}static int moxa_get_serial_info(struct moxa_port *info,				struct serial_struct __user *retinfo){	struct serial_struct tmp;	memset(&tmp, 0, sizeof(tmp));	tmp.type = info->type;	tmp.line = info->port;	tmp.port = 0;	tmp.irq = 0;	tmp.flags = info->asyncflags;	tmp.baud_base = 921600;	tmp.close_delay = info->close_delay;	tmp.closing_wait = info->closing_wait;	tmp.custom_divisor = 0;	tmp.hub6 = 0;	if(copy_to_user(retinfo, &tmp, sizeof(*retinfo)))		return -EFAULT;	return (0);}static int moxa_set_serial_info(struct moxa_port *info,				struct serial_struct __user *new_info){	struct serial_struct new_serial;	if(copy_from_user(&new_serial, new_info, sizeof(new_serial)))		return -EFAULT;	if ((new_serial.irq != 0) ||	    (new_serial.port != 0) ||//           (new_serial.type != info->type) ||	    (new_serial.custom_divisor != 0) ||	    (new_serial.baud_base != 921600))		return (-EPERM);	if (!capable(CAP_SYS_ADMIN)) {		if (((new_serial.flags & ~ASYNC_USR_MASK) !=		     (info->asyncflags & ~ASYNC_USR_MASK)))			return (-EPERM);	} else {		info->close_delay = new_serial.close_delay * HZ / 100;		info->closing_wait = new_serial.closing_wait * HZ / 100;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -