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

📄 moxa.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    (tty->termios->c_cflag & CLOCAL))		wake_up_interruptible(&ch->open_wait);}static void moxa_stop(struct tty_struct *tty){	struct moxa_str *ch = (struct moxa_str *) tty->driver_data;	if (ch == NULL)		return;	MoxaPortTxDisable(ch->port);	ch->statusflags |= TXSTOPPED;}static void moxa_start(struct tty_struct *tty){	struct moxa_str *ch = (struct moxa_str *) tty->driver_data;	if (ch == NULL)		return;	if (!(ch->statusflags & TXSTOPPED))		return;	MoxaPortTxEnable(ch->port);	ch->statusflags &= ~TXSTOPPED;}static void moxa_hangup(struct tty_struct *tty){	struct moxa_str *ch = (struct moxa_str *) tty->driver_data;	moxa_flush_buffer(tty);	shut_down(ch);	ch->event = 0;	ch->count = 0;	ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);	ch->tty = 0;	wake_up_interruptible(&ch->open_wait);}static void moxa_poll(unsigned long ignored){	register int card;	struct moxa_str *ch;	struct tty_struct *tp;	int i, ports;	moxaTimer_on = 0;	del_timer(&moxaTimer);	if (MoxaDriverPoll() < 0) {		moxaTimer.function = moxa_poll;		moxaTimer.expires = jiffies + (HZ / 50);		moxaTimer_on = 1;		add_timer(&moxaTimer);		return;	}	for (card = 0; card < MAX_BOARDS; card++) {		if ((ports = MoxaPortsOfCard(card)) <= 0)			continue;		ch = &moxaChannels[card * MAX_PORTS_PER_BOARD];		for (i = 0; i < ports; i++, ch++) {			if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)				continue;			if (!(ch->statusflags & THROTTLE) &&			    (MoxaPortRxQueue(ch->port) > 0))				receive_data(ch);			if ((tp = ch->tty) == 0)				continue;			if (ch->statusflags & LOWWAIT) {				if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) {					if (!tp->stopped) {						ch->statusflags &= ~LOWWAIT;						if ((tp->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&						  tp->ldisc.write_wakeup)							(tp->ldisc.write_wakeup) (tp);						wake_up_interruptible(&tp->write_wait);					}				}			}			if (!I_IGNBRK(tp) && (MoxaPortResetBrkCnt(ch->port) > 0)) {				tty_insert_flip_char(tp, 0, TTY_BREAK);				tty_schedule_flip(tp);			}			if (MoxaPortDCDChange(ch->port)) {				if (ch->asyncflags & ASYNC_CHECK_CD) {					if (MoxaPortDCDON(ch->port))						wake_up_interruptible(&ch->open_wait);					else {						set_bit(MOXA_EVENT_HANGUP, &ch->event);						MOD_DEC_USE_COUNT;						if (schedule_task(&ch->tqueue) == 0)							MOD_INC_USE_COUNT;					}				}			}		}	}	moxaTimer.function = moxa_poll;	moxaTimer.expires = jiffies + (HZ / 50);	moxaTimer_on = 1;	add_timer(&moxaTimer);}/******************************************************************************/static void set_tty_param(struct tty_struct *tty){	register struct termios *ts;	struct moxa_str *ch;	int rts, cts, txflow, rxflow, xany;	ch = (struct moxa_str *) tty->driver_data;	ts = tty->termios;	if (ts->c_cflag & CLOCAL)		ch->asyncflags &= ~ASYNC_CHECK_CD;	else		ch->asyncflags |= ASYNC_CHECK_CD;	rts = cts = txflow = rxflow = xany = 0;	if (ts->c_cflag & CRTSCTS)		rts = cts = 1;	if (ts->c_iflag & IXON)		txflow = 1;	if (ts->c_iflag & IXOFF)		rxflow = 1;	if (ts->c_iflag & IXANY)		xany = 1;	MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany);	MoxaPortSetTermio(ch->port, ts);}static int block_till_ready(struct tty_struct *tty, struct file *filp,			    struct moxa_str *ch){	DECLARE_WAITQUEUE(wait,current);	unsigned long flags;	int retval;	int do_clocal = C_CLOCAL(tty);	/*	 * If the device is in the middle of being closed, then block	 * until it's done, and then try again.	 */	if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {		if (ch->asyncflags & ASYNC_CLOSING)			interruptible_sleep_on(&ch->close_wait);#ifdef SERIAL_DO_RESTART		if (ch->asyncflags & ASYNC_HUP_NOTIFY)			return (-EAGAIN);		else			return (-ERESTARTSYS);#else		return (-EAGAIN);#endif	}	/*	 * If this is a callout device, then just make sure the normal	 * device isn't being used.	 */	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {		if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)			return (-EBUSY);		if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&		    (ch->asyncflags & ASYNC_SESSION_LOCKOUT) &&		    (ch->session != current->session))			return (-EBUSY);		if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&		    (ch->asyncflags & ASYNC_PGRP_LOCKOUT) &&		    (ch->pgrp != current->pgrp))			return (-EBUSY);		ch->asyncflags |= ASYNC_CALLOUT_ACTIVE;		return (0);	}	/*	 * If non-blocking mode is set, then make the check up front	 * and then exit.	 */	if (filp->f_flags & O_NONBLOCK) {		if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)			return (-EBUSY);		ch->asyncflags |= ASYNC_NORMAL_ACTIVE;		return (0);	}	/*	 * Block waiting for the carrier detect and the line to become free	 */	retval = 0;	add_wait_queue(&ch->open_wait, &wait);#ifdef SERIAL_DEBUG_OPEN	printk("block_til_ready before block: ttys%d, count = %d\n",	       ch->line, ch->count);#endif	save_flags(flags);	cli();	if (!tty_hung_up_p(filp))		ch->count--;	restore_flags(flags);	ch->blocked_open++;	while (1) {		current->state = TASK_INTERRUPTIBLE;		if (tty_hung_up_p(filp) ||		    !(ch->asyncflags & ASYNC_INITIALIZED)) {#ifdef SERIAL_DO_RESTART			if (ch->asyncflags & ASYNC_HUP_NOTIFY)				retval = -EAGAIN;			else				retval = -ERESTARTSYS;#else			retval = -EAGAIN;#endif			break;		}		if (!(ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&		    !(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||						MoxaPortDCDON(ch->port)))			break;		if (signal_pending(current)) {			retval = -ERESTARTSYS;			break;		}		schedule();	}	current->state = TASK_RUNNING;	remove_wait_queue(&ch->open_wait, &wait);	if (!tty_hung_up_p(filp))		ch->count++;	ch->blocked_open--;#ifdef SERIAL_DEBUG_OPEN	printk("block_til_ready after blocking: ttys%d, count = %d\n",	       ch->line, ch->count);#endif	if (retval)		return (retval);	ch->asyncflags |= ASYNC_NORMAL_ACTIVE;	return (0);}static void setup_empty_event(struct tty_struct *tty){	struct moxa_str *ch = tty->driver_data;	unsigned long flags;	save_flags(flags);	cli();	ch->statusflags |= EMPTYWAIT;	moxaEmptyTimer_on[ch->port] = 0;	del_timer(&moxaEmptyTimer[ch->port]);	moxaEmptyTimer[ch->port].expires = jiffies + HZ;	moxaEmptyTimer_on[ch->port] = 1;	add_timer(&moxaEmptyTimer[ch->port]);	restore_flags(flags);}static void check_xmit_empty(unsigned long data){	struct moxa_str *ch;	ch = (struct moxa_str *) data;	moxaEmptyTimer_on[ch->port] = 0;	del_timer(&moxaEmptyTimer[ch->port]);	if (ch->tty && (ch->statusflags & EMPTYWAIT)) {		if (MoxaPortTxQueue(ch->port) == 0) {			ch->statusflags &= ~EMPTYWAIT;			if ((ch->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&			    ch->tty->ldisc.write_wakeup)				(ch->tty->ldisc.write_wakeup) (ch->tty);			wake_up_interruptible(&ch->tty->write_wait);			return;		}		moxaEmptyTimer[ch->port].expires = jiffies + HZ;		moxaEmptyTimer_on[ch->port] = 1;		add_timer(&moxaEmptyTimer[ch->port]);	} else		ch->statusflags &= ~EMPTYWAIT;}static void shut_down(struct moxa_str *ch){	struct tty_struct *tp;	if (!(ch->asyncflags & ASYNC_INITIALIZED))		return;	tp = ch->tty;	MoxaPortDisable(ch->port);	/*	 * If we're a modem control device and HUPCL is on, drop RTS & DTR.	 */	if (tp->termios->c_cflag & HUPCL)		MoxaPortLineCtrl(ch->port, 0, 0);	ch->asyncflags &= ~ASYNC_INITIALIZED;}static void receive_data(struct moxa_str *ch){	struct tty_struct *tp;	struct termios *ts;	int i, count, rc, space;	unsigned char *charptr, *flagptr;	unsigned long flags;	ts = 0;	tp = ch->tty;	if (tp)		ts = tp->termios;	/**************************************************	if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {	*****************************************************/	if (!tp || !ts) {		MoxaPortFlushData(ch->port, 0);		return;	}	space = TTY_FLIPBUF_SIZE - tp->flip.count;	if (space <= 0)		return;	charptr = tp->flip.char_buf_ptr;	flagptr = tp->flip.flag_buf_ptr;	rc = tp->flip.count;	save_flags(flags);	cli();	count = MoxaPortReadData(ch->port, charptr, space);	restore_flags(flags);	for (i = 0; i < count; i++)		*flagptr++ = 0;	charptr += count;	rc += count;	tp->flip.count = rc;	tp->flip.char_buf_ptr = charptr;	tp->flip.flag_buf_ptr = flagptr;	tty_schedule_flip(ch->tty);}#define Magic_code	0x404/* *    System Configuration *//* *    for C218 BIOS initialization */#define C218_ConfBase	0x800#define C218_status	(C218_ConfBase + 0)	/* BIOS running status    */#define C218_diag	(C218_ConfBase + 2)	/* diagnostic status      */#define C218_key	(C218_ConfBase + 4)	/* WORD (0x218 for C218) */#define C218DLoad_len	(C218_ConfBase + 6)	/* WORD           */#define C218check_sum	(C218_ConfBase + 8)	/* BYTE           */#define C218chksum_ok	(C218_ConfBase + 0x0a)	/* BYTE (1:ok)            */#define C218_TestRx	(C218_ConfBase + 0x10)	/* 8 bytes for 8 ports    */#define C218_TestTx	(C218_ConfBase + 0x18)	/* 8 bytes for 8 ports    */#define C218_RXerr	(C218_ConfBase + 0x20)	/* 8 bytes for 8 ports    */#define C218_ErrFlag	(C218_ConfBase + 0x28)	/* 8 bytes for 8 ports    */#define C218_LoadBuf	0x0F00#define C218_KeyCode	0x218#define CP204J_KeyCode	0x204/* *    for C320 BIOS initialization */#define C320_ConfBase	0x800#define C320_LoadBuf	0x0f00#define STS_init	0x05	/* for C320_status        */#define C320_status	C320_ConfBase + 0	/* BIOS running status    */#define C320_diag	C320_ConfBase + 2	/* diagnostic status      */#define C320_key	C320_ConfBase + 4	/* WORD (0320H for C320) */#define C320DLoad_len	C320_ConfBase + 6	/* WORD           */#define C320check_sum	C320_ConfBase + 8	/* WORD           */#define C320chksum_ok	C320_ConfBase + 0x0a	/* WORD (1:ok)            */#define C320bapi_len	C320_ConfBase + 0x0c	/* WORD           */#define C320UART_no	C320_ConfBase + 0x0e	/* WORD           */#define C320_KeyCode	0x320#define FixPage_addr	0x0000	/* starting addr of static page  */#define DynPage_addr	0x2000	/* starting addr of dynamic page */#define C218_start	0x3000	/* starting addr of C218 BIOS prg */#define Control_reg	0x1ff0	/* select page and reset control */#define HW_reset	0x80/* *    Function Codes */#define FC_CardReset	0x80#define FC_ChannelReset 1	/* C320 firmware not supported */#define FC_EnableCH	2#define FC_DisableCH	3#define FC_SetParam	4#define FC_SetMode	5#define FC_SetRate	6#define FC_LineControl	7#define FC_LineStatus	8#define FC_XmitControl	9#define FC_FlushQueue	10#define FC_SendBreak	11#define FC_StopBreak	12#define FC_LoopbackON	13#define FC_LoopbackOFF	14#define FC_ClrIrqTable	15#define FC_SendXon	16#define FC_SetTermIrq	17	/* C320 firmware not supported */#define FC_SetCntIrq	18	/* C320 firmware not supported */#define FC_SetBreakIrq	19#define FC_SetLineIrq	20#define FC_SetFlowCtl	21#define FC_GenIrq	22#define FC_InCD180	23#define FC_OutCD180	24#define FC_InUARTreg	23#define FC_OutUARTreg	24#define FC_SetXonXoff	25#define FC_OutCD180CCR	26#define FC_ExtIQueue	27#define FC_ExtOQueue	28#define FC_ClrLineIrq	29#define FC_HWFlowCtl	30#define FC_GetClockRate 35#define FC_SetBaud	36#define FC_SetDataMode  41#define FC_GetCCSR      43#define FC_GetDataError 45#define FC_RxControl	50#define FC_ImmSend	51#define FC_SetXonState	52#define FC_SetXoffState	53#define FC_SetRxFIFOTrig 54#define FC_SetTxFIFOCnt 55#define FC_UnixRate	56#define FC_UnixResetTimer 57#define	RxFIFOTrig1	0#define	RxFIFOTrig4	1#define	RxFIFOTrig8	2#define	RxFIFOTrig14	3/* *    Dual-Ported RAM */#define DRAM_global	0#define INT_data	(DRAM_global + 0)#define Config_base	(DRAM_global + 0x108)#define IRQindex	(INT_data + 0)#define IRQpending	(INT_data + 4)#define IRQtable	(INT_data + 8)/* *    Interrupt Status */#define IntrRx		0x01	/* receiver data O.K.             */#define IntrTx		0x02	/* transmit buffer empty  */#define IntrFunc	0x04	/* function complete              */#define IntrBreak	0x08	/* received break         */#define IntrLine	0x10	/* line status change				   for transmitter                */

⌨️ 快捷键说明

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