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

📄 i2lib.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	set_current_state( TASK_INTERRUPTIBLE );	serviceOutgoingFifo( pB );		schedule();	// Now we take our interruptible sleep on	// Clean up the queue	set_current_state( TASK_RUNNING );	remove_wait_queue(&(pCh->pBookmarkWait), &wait);	// if expires == 0 then timer poped, then do not need to del_timer	if ((timeout > 0) && pCh->BookmarkTimer.expires && 	                     time_before(jiffies, pCh->BookmarkTimer.expires)) {		del_timer( &(pCh->BookmarkTimer) );		pCh->BookmarkTimer.expires = 0;		ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires );	}	ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires );	return;}//******************************************************************************// Function:   i2OutputFree(pCh)// Parameters: Pointer to a channel structure// Returns:    Space in output buffer//// Description:// Returns -1 if very gross error. Otherwise returns the amount of bytes still// free in the output buffer.//******************************************************************************static inti2OutputFree(i2ChanStrPtr pCh){	int amountToMove;	unsigned long flags;	// Ensure channel structure seems real	if ( !i2Validate ( pCh ) ) {		return -1;	}	READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);	amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;	READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);	if (amountToMove < 0) {		amountToMove += OBUF_SIZE;	}	// If this is negative, we will discover later	amountToMove -= sizeof(i2DataHeader);	return (amountToMove < 0) ? 0 : amountToMove;}static voidip2_owake( PTTY tp){	i2ChanStrPtr  pCh;	if (tp == NULL) return;	pCh = tp->driver_data;	ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags,			(1 << TTY_DO_WRITE_WAKEUP) );	wake_up_interruptible ( &tp->write_wait );	if ( ( tp->flags & (1 << TTY_DO_WRITE_WAKEUP) ) 	  && tp->ldisc.write_wakeup )	{		(tp->ldisc.write_wakeup) ( tp );		ip2trace (CHANN, ITRC_SICMD, 11, 0 );	}}static inline voidset_baud_params(i2eBordStrPtr pB) {	int i,j;	i2ChanStrPtr  *pCh;	pCh = (i2ChanStrPtr *) pB->i2eChannelPtr;	for (i = 0; i < ABS_MAX_BOXES; i++) {		if (pB->channelBtypes.bid_value[i]) {			if (BID_HAS_654(pB->channelBtypes.bid_value[i])) {				for (j = 0; j < ABS_BIGGEST_BOX; j++) {					if (pCh[i*16+j] == NULL)						break;					(pCh[i*16+j])->BaudBase    = 921600;	// MAX for ST654					(pCh[i*16+j])->BaudDivisor = 96;				}			} else {	// has cirrus cd1400				for (j = 0; j < ABS_BIGGEST_BOX; j++) {					if (pCh[i*16+j] == NULL)						break;					(pCh[i*16+j])->BaudBase    = 115200;	// MAX for CD1400					(pCh[i*16+j])->BaudDivisor = 12;				}			}		}	}}//******************************************************************************// Function:   i2StripFifo(pB)// Parameters: Pointer to a board structure// Returns:    ?//// Description:// Strips all the available data from the incoming FIFO, identifies the type of// packet, and either buffers the data or does what needs to be done.//// Note there is no overflow checking here: if the board sends more data than it// ought to, we will not detect it here, but blindly overflow...//******************************************************************************// A buffer for reading in blocks for unknown channelsstatic unsigned char junkBuffer[IBUF_SIZE];// A buffer to read in a status packet. Because of the size of the count field// for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZEstatic unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4];// This table changes the bit order from MSR order given by STAT_MODEM packet to// status bits used in our library.static char xlatDss[16] = {0      | 0     | 0      | 0      ,0      | 0     | 0      | I2_CTS ,0      | 0     | I2_DSR | 0      ,0      | 0     | I2_DSR | I2_CTS ,0      | I2_RI | 0      | 0      ,0      | I2_RI | 0      | I2_CTS ,0      | I2_RI | I2_DSR | 0      ,0      | I2_RI | I2_DSR | I2_CTS ,I2_DCD | 0     | 0      | 0      ,I2_DCD | 0     | 0      | I2_CTS ,I2_DCD | 0     | I2_DSR | 0      ,I2_DCD | 0     | I2_DSR | I2_CTS ,I2_DCD | I2_RI | 0      | 0      ,I2_DCD | I2_RI | 0      | I2_CTS ,I2_DCD | I2_RI | I2_DSR | 0      ,I2_DCD | I2_RI | I2_DSR | I2_CTS };static inline voidi2StripFifo(i2eBordStrPtr pB){	i2ChanStrPtr pCh;	int channel;	int count;	unsigned short stuffIndex;	int amountToRead;	unsigned char *pc, *pcLimit;	unsigned char uc;	unsigned char dss_change;	unsigned long bflags,cflags;//	ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 );	while (HAS_INPUT(pB)) {//		ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 );		// Process packet from fifo a one atomic unit		WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock,bflags);   		// The first word (or two bytes) will have channel number and type of		// packet, possibly other information		pB->i2eLeadoffWord[0] = iiReadWord(pB);		switch(PTYPE_OF(pB->i2eLeadoffWord))		{		case PTYPE_DATA:			pB->got_input = 1;//			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 );			channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */			count = iiReadWord(pB);          /* Count is in the next word */// NEW: Check the count for sanity! Should the hardware fail, our death// is more pleasant. While an oversize channel is acceptable (just more// than the driver supports), an over-length count clearly means we are// sick!			if ( ((unsigned int)count) > IBUF_SIZE ) {				pB->i2eFatal = 2;				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);				return;     /* Bail out ASAP */			}			// Channel is illegally big ?			if ((channel >= pB->i2eChannelCnt) ||				(NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])))			{				iiReadBuf(pB, junkBuffer, count);				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);				break;         /* From switch: ready for next packet */			}			// Channel should be valid, then			// If this is a hot-key, merely post its receipt for now. These are			// always supposed to be 1-byte packets, so we won't even check the			// count. Also we will post an acknowledgement to the board so that			// more data can be forthcoming. Note that we are not trying to use			// these sequences in this driver, merely to robustly ignore them.			if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY)			{				pCh->hotKeyIn = iiReadWord(pB) & 0xff;				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);				i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK);				break;   /* From the switch: ready for next packet */			}			// Normal data! We crudely assume there is room for the data in our			// buffer because the board wouldn't have exceeded his credit limit.			WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,cflags);													// We have 2 locks now			stuffIndex = pCh->Ibuf_stuff;			amountToRead = IBUF_SIZE - stuffIndex;			if (amountToRead > count)				amountToRead = count;			// stuffIndex would have been already adjusted so there would 			// always be room for at least one, and count is always at least			// one.			iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);			pCh->icount.rx += amountToRead;			// Update the stuffIndex by the amount of data moved. Note we could			// never ask for more data than would just fit. However, we might			// have read in one more byte than we wanted because the read			// rounds up to even bytes. If this byte is on the end of the			// packet, and is padding, we ignore it. If the byte is part of			// the actual data, we need to move it.			stuffIndex += amountToRead;			if (stuffIndex >= IBUF_SIZE) {				if ((amountToRead & 1) && (count > amountToRead)) {					pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE];					amountToRead++;					stuffIndex = 1;				} else {					stuffIndex = 0;				}			}			// If there is anything left over, read it as well			if (count > amountToRead) {				amountToRead = count - amountToRead;				iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);				pCh->icount.rx += amountToRead;				stuffIndex += amountToRead;			}			// Update stuff index			pCh->Ibuf_stuff = stuffIndex;			WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,cflags);			WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);#ifdef USE_IQ			schedule_work(&pCh->tqueue_input);#else			do_input(pCh);#endif			// Note we do not need to maintain any flow-control credits at this			// time:  if we were to increment .asof and decrement .room, there			// would be no net effect. Instead, when we strip data, we will			// increment .asof and leave .room unchanged.			break;   // From switch: ready for next packet		case PTYPE_STATUS:			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 );      			count = CMD_COUNT_OF(pB->i2eLeadoffWord);			iiReadBuf(pB, cmdBuffer, count);			// We can release early with buffer grab			WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);			pc = cmdBuffer;			pcLimit = &(cmdBuffer[count]);			while (pc < pcLimit) {				channel = *pc++;				ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc );				/* check for valid channel */				if (channel < pB->i2eChannelCnt					 && 					 (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL					)				{					dss_change = 0;					switch (uc = *pc++)					{					/* Breaks and modem signals are easy: just update status */					case STAT_CTS_UP:						if ( !(pCh->dataSetIn & I2_CTS) )						{							pCh->dataSetIn |= I2_DCTS;							pCh->icount.cts++;							dss_change = 1;						}						pCh->dataSetIn |= I2_CTS;						break;					case STAT_CTS_DN:						if ( pCh->dataSetIn & I2_CTS )						{							pCh->dataSetIn |= I2_DCTS;							pCh->icount.cts++;							dss_change = 1;						}						pCh->dataSetIn &= ~I2_CTS;						break;					case STAT_DCD_UP:						ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn );						if ( !(pCh->dataSetIn & I2_DCD) )						{							ip2trace (CHANN, ITRC_MODEM, 2, 0 );							pCh->dataSetIn |= I2_DDCD;							pCh->icount.dcd++;							dss_change = 1;						}						pCh->dataSetIn |= I2_DCD;						ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn );						break;					case STAT_DCD_DN:						ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn );						if ( pCh->dataSetIn & I2_DCD )						{							ip2trace (channel, ITRC_MODEM, 5, 0 );							pCh->dataSetIn |= I2_DDCD;							pCh->icount.dcd++;							dss_change = 1;						}						pCh->dataSetIn &= ~I2_DCD;						ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn );						break;					case STAT_DSR_UP:						if ( !(pCh->dataSetIn & I2_DSR) )						{							pCh->dataSetIn |= I2_DDSR;							pCh->icount.dsr++;							dss_change = 1;						}						pCh->dataSetIn |= I2_DSR;						break;					case STAT_DSR_DN:						if ( pCh->dataSetIn & I2_DSR )						{							pCh->dataSetIn |= I2_DDSR;							pCh->icount.dsr++;							dss_change = 1;						}						pCh->dataSetIn &= ~I2_DSR;						break;					case STAT_RI_UP:						if ( !(pCh->dataSetIn & I2_RI) )						{							pCh->dataSetIn |= I2_DRI;							pCh->icount.rng++;							dss_change = 1;						}						pCh->dataSetIn |= I2_RI ;						break;					case STAT_RI_DN:						// to be compat with serial.c						//if ( pCh->dataSetIn & I2_RI )						//{						//	pCh->dataSetIn |= I2_DRI;						//	pCh->icount.rng++; 						//	dss_change = 1;						//}						pCh->dataSetIn &= ~I2_RI ;						break;					case STAT_BRK_DET:						pCh->dataSetIn |= I2_BRK;						pCh->icount.brk++;						dss_change = 1;						break;					// Bookmarks? one less request we're waiting for					case STAT_BMARK:						pCh->bookMarks--;						if (pCh->bookMarks <= 0 ) {							pCh->bookMarks = 0;							wake_up_interruptible( &pCh->pBookmarkWait );						ip2trace (channel, ITRC_DRAIN, 20, 1, pCh->BookmarkTimer.expires );						}						break;					// Flow control packets? Update the new credits, and if					// someone was waiting for output, queue him up again.					case STAT_FLOW:						pCh->outfl.room =							((flowStatPtr)pc)->room -							(pCh->outfl.asof - ((flowStatPtr)pc)->asof);						ip2trace (channel, ITRC_STFLW, 1, 1, pCh->outfl.room );						if (pCh->channelNeeds & NEED_CREDIT)						{							ip2trace (channel, ITRC_STFLW, 2, 1, pCh->channelNeeds);							pCh->channelNeeds &= ~NEED_CREDIT;							i2QueueNeeds(pB, pCh, NEED_INLINE);							if ( pCh->pTTY )								ip2_owake(pCh->pTTY);						}						ip2trace (channel, ITRC_STFLW, 3, 1, pCh->channelNeeds);						pc += sizeof(flowStat);						break;					/* Special packets: */					/* Just copy the information into the channel structure */

⌨️ 快捷键说明

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