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

📄 ip2main.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	CHANNEL_OF(tempCommand) = 0;	PTYPE_OF(tempCommand) = PTYPE_BYPASS;	CMD_COUNT_OF(tempCommand) = 1;	(CMD_OF(tempCommand))[0] = 84;	/* get BOX_IDS */	iiWriteBuf(pB, tempCommand, 3);#ifdef XXX	// enable heartbeat for test porpoises	CHANNEL_OF(tempCommand) = 0;	PTYPE_OF(tempCommand) = PTYPE_BYPASS;	CMD_COUNT_OF(tempCommand) = 2;	(CMD_OF(tempCommand))[0] = 44;	/* get ping */	(CMD_OF(tempCommand))[1] = 200;	/* 200 ms */	WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);	iiWriteBuf(pB, tempCommand, 4);	WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);#endif	iiEnableMailIrq(pB);	iiSendPendingMail(pB);}/******************************************************************************//* Interrupt Handler Section                                                  *//******************************************************************************/static inline voidservice_all_boards(){	int i;	i2eBordStrPtr  pB;	/* Service every board on the list */	for( i = 0; i < IP2_MAX_BOARDS; ++i ) {		pB = i2BoardPtrTable[i];		if ( pB ) {			i2ServiceBoard( pB );		}	}}#ifdef USE_IQIstatic struct tq_struct senior_service ={	// it's the death that worse than fate	NULL,	0,	(void(*)(void*)) service_all_boards,	NULL,	//later - board address XXX};#endif/******************************************************************************//* Function:   ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)    *//* Parameters: irq - interrupt number                                         *//*             pointer to optional device ID structure                        *//*             pointer to register structure                                  *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//*                                                                            *//*                                                                            *//******************************************************************************/static voidip2_interrupt(int irq, void *dev_id, struct pt_regs * regs){	int i;	i2eBordStrPtr  pB;#ifdef IP2DEBUG_TRACE	ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq );#endif#ifdef USE_IQI	queue_task(&senior_service, &tq_immediate);	mark_bh(IMMEDIATE_BH);#else	/* Service just the boards on the list using this irq */	for( i = 0; i < i2nBoards; ++i ) {		pB = i2BoardPtrTable[i];		if ( pB && (pB->i2eUsingIrq == irq) ) {			i2ServiceBoard( pB );		}	}#endif /* USE_IQI */	++irq_counter;#ifdef IP2DEBUG_TRACE	ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );#endif}/******************************************************************************//* Function:   ip2_poll(unsigned long arg)                                    *//* Parameters: ?                                                              *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//* This function calls the library routine i2ServiceBoard for each board in   *//* the board table. This is used instead of the interrupt routine when polled *//* mode is specified.                                                         *//******************************************************************************/static voidip2_poll(unsigned long arg){#ifdef IP2DEBUG_TRACE	ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );#endif	TimerOn = 0; // it's the truth but not checked in service	bh_counter++; #ifdef USE_IQI	queue_task(&senior_service, &tq_immediate);	mark_bh(IMMEDIATE_BH);#else	// Just polled boards, service_all might be better	ip2_interrupt(0, NULL, NULL);#endif /* USE_IQI */	PollTimer.expires = POLL_TIMEOUT;	add_timer( &PollTimer );	TimerOn = 1;#ifdef IP2DEBUG_TRACE	ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );#endif}static inline void do_input( i2ChanStrPtr pCh ){	unsigned long flags;#ifdef IP2DEBUG_TRACE	ip2trace(CHANN, ITRC_INPUT, 21, 0 );#endif	// Data input	if ( pCh->pTTY != NULL ) {		READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)		if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {			READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)			i2Input( pCh );		} else			READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)	} else {#ifdef IP2DEBUG_TRACE		ip2trace(CHANN, ITRC_INPUT, 22, 0 );#endif		i2InputFlush( pCh );	}}// code duplicated from n_tty (ldisc)static inline void isig(int sig, struct tty_struct *tty, int flush){	if (tty->pgrp > 0)		kill_pg(tty->pgrp, sig, 1);	if (flush || !L_NOFLSH(tty)) {		if ( tty->ldisc.flush_buffer )  			tty->ldisc.flush_buffer(tty);		i2InputFlush( tty->driver_data );	}}static inline voiddo_status( i2ChanStrPtr pCh ){	int status;	status =  i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );#ifdef IP2DEBUG_TRACE	ip2trace (CHANN, ITRC_STATUS, 21, 1, status );#endif	if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {		if ( (status & I2_BRK) ) {			// code duplicated from n_tty (ldisc)			if (I_IGNBRK(pCh->pTTY))				goto skip_this;			if (I_BRKINT(pCh->pTTY)) {				isig(SIGINT, pCh->pTTY, 1);				goto skip_this;			}			wake_up_interruptible(&pCh->pTTY->read_wait);		}#ifdef NEVER_HAPPENS_AS_SETUP_XXX	// and can't work because we don't know the_char	// as the_char is reported on a seperate path	// The intelligent board does this stuff as setup	{	char brkf = TTY_NORMAL;	unsigned char brkc = '\0';	unsigned char tmp;		if ( (status & I2_BRK) ) {			brkf = TTY_BREAK;			brkc = '\0';		} 		else if (status & I2_PAR) {			brkf = TTY_PARITY;			brkc = the_char;		} else if (status & I2_FRA) {			brkf = TTY_FRAME;			brkc = the_char;		} else if (status & I2_OVR) {			brkf = TTY_OVERRUN;			brkc = the_char;		}		tmp = pCh->pTTY->real_raw;		pCh->pTTY->real_raw = 0;		pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );		pCh->pTTY->real_raw = tmp;	}#endif /* NEVER_HAPPENS_AS_SETUP_XXX */	}skip_this:	if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {		wake_up_interruptible(&pCh->delta_msr_wait);		if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {			if ( status & I2_DCD ) {				if ( pCh->wopen ) {					wake_up_interruptible ( &pCh->open_wait );				}			} else if ( !(pCh->flags & ASYNC_CALLOUT_ACTIVE) ) {				if (pCh->pTTY &&  (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {					tty_hangup( pCh->pTTY );				}			}		}	}#ifdef IP2DEBUG_TRACE	ip2trace (CHANN, ITRC_STATUS, 26, 0 );#endif}/******************************************************************************//* Device Open/Close/Ioctl Entry Point Section                                *//******************************************************************************//******************************************************************************//* Function:   open_sanity_check()                                            *//* Parameters: Pointer to tty structure                                       *//*             Pointer to file structure                                      *//* Returns:    Success or failure                                             *//*                                                                            *//* Description:                                                               *//* Verifies the structure magic numbers and cross links.                      *//******************************************************************************/#ifdef IP2DEBUG_OPENstatic void open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd ){	if ( pBrd->i2eValid != I2E_MAGIC ) {		printk(KERN_ERR "IP2: invalid board structure\n" );	} else if ( pBrd != pCh->pMyBord ) {		printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",			 pCh->pMyBord );	} else if ( pBrd->i2eChannelCnt < pCh->port_index ) {		printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );	} else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {	} else {		printk(KERN_INFO "IP2: all pointers check out!\n" );	}}#endif/******************************************************************************//* Function:   ip2_open()                                                     *//* Parameters: Pointer to tty structure                                       *//*             Pointer to file structure                                      *//* Returns:    Success or failure                                             *//*                                                                            *//* Description: (MANDATORY)                                                   *//* A successful device open has to run a gauntlet of checks before it         *//* completes. After some sanity checking and pointer setup, the function      *//* blocks until all conditions are satisfied. It then initialises the port to *//* the default characteristics and returns.                                   *//******************************************************************************/static intip2_open( PTTY tty, struct file *pFile ){	int rc = 0;	int do_clocal = 0;	i2ChanStrPtr  pCh = DevTable[MINOR(tty->device)];#ifdef IP2DEBUG_TRACE	ip2trace (MINOR(tty->device), ITRC_OPEN, ITRC_ENTER, 0 );#endif	if ( pCh == NULL ) {		return -ENODEV;	}	/* Setup pointer links in device and tty structures */	pCh->pTTY = tty;	tty->driver_data = pCh;	MOD_INC_USE_COUNT;#ifdef IP2DEBUG_OPEN	printk(KERN_DEBUG \			"IP2:open(tty=%p,pFile=%p):dev=%x,maj=%d,min=%d,ch=%d,idx=%d\n",	       tty, pFile, tty->device, MAJOR(tty->device), MINOR(tty->device),			 pCh->infl.hd.i2sChannel, pCh->port_index);	open_sanity_check ( pCh, pCh->pMyBord );#endif	i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);	pCh->dataSetOut |= (I2_DTR | I2_RTS);	serviceOutgoingFifo( pCh->pMyBord );	/* Block here until the port is ready (per serial and istallion) */	/*	 * 1. If the port is in the middle of closing wait for the completion	 *    and then return the appropriate error.	 */	if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {		if ( pCh->flags & ASYNC_CLOSING ) {			interruptible_sleep_on( &pCh->close_wait);		}		if ( tty_hung_up_p(pFile) ) {			return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;		}	}	/*	 * 2. If this is a callout device, make sure the normal port is not in	 *    use, and that someone else doesn't have the callout device locked.	 *    (These are the only tests the standard serial driver makes for	 *    callout devices.)	 */	if ( tty->driver.subtype == SERIAL_TYPE_CALLOUT ) {		if ( pCh->flags & ASYNC_NORMAL_ACTIVE ) {			return -EBUSY;		}		if ( ( pCh->flags & ASYNC_CALLOUT_ACTIVE )  &&		    ( pCh->flags & ASYNC_SESSION_LOCKOUT ) &&		    ( pCh->session != current->session ) ) {			return -EBUSY;		}		if ( ( pCh->flags & ASYNC_CALLOUT_ACTIVE ) &&		    ( pCh->flags & ASYNC_PGRP_LOCKOUT )   &&		    ( pCh->pgrp != current->pgrp ) ) {			return -EBUSY;		}		pCh->flags |= ASYNC_CALLOUT_ACTIVE;		goto noblock;	}	/*	 * 3. Handle a non-blocking open of a normal port.	 */	if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {		if ( pCh->flags & ASYNC_CALLOUT_ACTIVE ) {			return -EBUSY;		}		pCh->flags |= ASYNC_NORMAL_ACTIVE;		goto noblock;	}	/*	 * 4. Now loop waiting for the port to be free and carrier present	 *    (if required).	 */	if ( pCh->flags & ASYNC_CALLOUT_ACTIVE ) {		if ( pCh->NormalTermios.c_cflag & CLOCAL ) {			do_clocal = 1;		}	} else {		if ( tty->termios->c_cflag & CLOCAL ) {			do_clocal = 1;		}	}#ifdef IP2DEBUG_OPEN	printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);#endif	++pCh->wopen;	for(;;) {		if ( !(pCh->flags & ASYNC_CALLOUT_ACTIVE)) {			i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);			pCh->dataSetOut |= (I2_DTR | I2_RTS);			serviceOutgoingFifo( pCh->pMyBord );		}		if ( tty_hung_up_p(pFile) ) {			return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;		}		if ( !(pCh->flags & ASYNC_CALLOUT_ACTIVE) &&				!(pCh->flags & ASYNC_CLOSING) && 				(do_clocal || (pCh->dataSetIn & I2_DCD) )) {			rc = 0;			break;		}#ifdef IP2DEBUG_OPEN		printk(KERN_DEBUG "ASYNC_CALLOUT_ACTIVE = %s\n",			(pCh->flags & ASYNC_CALLOUT_ACTIVE)?"True":"False");		printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",

⌨️ 快捷键说明

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