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

📄 i2ellis.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
			if (pB->i2ePom.e.porPorts1 != 8)			{				COMPLETE(pB, I2EE_INCONSIST);			}			break;		case POR_ID_II_6:			pB->i2eGoodMap[0] =			pB->i2eChannelMap[0] = 0x3f;  // Six Port			if (pB->i2ePom.e.porPorts1 != 6)			{				COMPLETE(pB, I2EE_INCONSIST);			}			break;		}		// Fix up the "good channel list based on any errors reported.		if (pB->i2ePom.e.porDiag1 & POR_BAD_UART1)		{			pB->i2eGoodMap[0] &= ~0x0f;		}		if (pB->i2ePom.e.porDiag1 & POR_BAD_UART2)		{			pB->i2eGoodMap[0] &= ~0xf0;		}		break;   // POR_ID_FII case	case POR_ID_FIIEX:   // IntelliPort-IIEX		pB->i2eFifoStyle = FIFO_IIEX;		itemp = pB->i2ePom.e.porFifoSize;		// Implicit assumption that fifo would not grow beyond 32k, 		// nor would ever be less than 256.		if (itemp < 8 || itemp > 15)		{			COMPLETE(pB, I2EE_INCONSIST);		}		pB->i2eFifoSize = (1 << itemp);		// These are based on what P.O.S.T thinks should be there, based on		// box ID registers		ilimit = pB->i2ePom.e.porNumBoxes;		if (ilimit > ABS_MAX_BOXES)		{			ilimit = ABS_MAX_BOXES;		}		// For as many boxes as EXIST, gives the type of box.		// Added 8/6/93: check for the ISA-4 (asic) which looks like an		// expandable but for whom "8 or 16?" is not the right question.		utemp = pB->i2ePom.e.porFlags;		if (utemp & POR_CEX4)		{			pB->i2eChannelMap[0] = 0x000f;		} else {			utemp &= POR_BOXES;			for (itemp = 0; itemp < ilimit; itemp++)			{				pB->i2eChannelMap[itemp] = 					((utemp & POR_BOX_16) ? 0xffff : 0x00ff);				utemp >>= 1;			}		}		// These are based on what P.O.S.T actually found.		utemp = (pB->i2ePom.e.porPorts2 << 8) + pB->i2ePom.e.porPorts1;		for (itemp = 0; itemp < ilimit; itemp++)		{			pB->i2eGoodMap[itemp] = 0;			if (utemp & 1) pB->i2eGoodMap[itemp] |= 0x000f;			if (utemp & 2) pB->i2eGoodMap[itemp] |= 0x00f0;			if (utemp & 4) pB->i2eGoodMap[itemp] |= 0x0f00;			if (utemp & 8) pB->i2eGoodMap[itemp] |= 0xf000;			utemp >>= 4;		}		// Now determine whether we should transfer in 8 or 16-bit mode.		switch (pB->i2ePom.e.porBus & (POR_BUS_SLOT16 | POR_BUS_DIP16) )		{		case POR_BUS_SLOT16 | POR_BUS_DIP16:			pB->i2eDataWidth16 = YES;			pB->i2eMaxIrq = 15;			break;		case POR_BUS_SLOT16:			pB->i2eDataWidth16 = NO;			pB->i2eMaxIrq = 15;			break;		case 0:		case POR_BUS_DIP16:     // In an 8-bit slot, DIP switch don't care.		default:			pB->i2eDataWidth16 = NO;			pB->i2eMaxIrq = 7;			break;		}		break;   // POR_ID_FIIEX case	default:    // Unknown type of board		COMPLETE(pB, I2EE_BAD_FAMILY);		break;	}  // End the switch based on family	// Temporarily, claim there is no room in the outbound fifo. 	// We will maintain this whenever we check for an empty outbound FIFO.	pB->i2eFifoRemains = 0;	// Now, based on the bus type, should we expect to be able to re-configure	// interrupts (say, for testing purposes).	switch (pB->i2ePom.e.porBus & POR_BUS_TYPE)	{	case POR_BUS_T_ISA:	case POR_BUS_T_UNK:  // If the type of bus is undeclared, assume ok.		pB->i2eChangeIrq = YES;		break;	case POR_BUS_T_MCA:	case POR_BUS_T_EISA:		pB->i2eChangeIrq = NO;		break;	default:		COMPLETE(pB, I2EE_BADBUS);	}	if (pB->i2eDataWidth16 == YES)	{		pB->i2eWriteBuf  = iiWriteBuf16;		pB->i2eReadBuf   = iiReadBuf16;		pB->i2eWriteWord = iiWriteWord16;		pB->i2eReadWord  = iiReadWord16;	} else {		pB->i2eWriteBuf  = iiWriteBuf8;		pB->i2eReadBuf   = iiReadBuf8;		pB->i2eWriteWord = iiWriteWord8;		pB->i2eReadWord  = iiReadWord8;	}	switch(pB->i2eFifoStyle)	{	case FIFO_II:		pB->i2eWaitForTxEmpty = iiWaitForTxEmptyII;		pB->i2eTxMailEmpty    = iiTxMailEmptyII;		pB->i2eTrySendMail    = iiTrySendMailII;		pB->i2eGetMail        = iiGetMailII;		pB->i2eEnableMailIrq  = iiEnableMailIrqII;		pB->i2eWriteMask      = iiWriteMaskII;		break;	case FIFO_IIEX:		pB->i2eWaitForTxEmpty = iiWaitForTxEmptyIIEX;		pB->i2eTxMailEmpty    = iiTxMailEmptyIIEX;		pB->i2eTrySendMail    = iiTrySendMailIIEX;		pB->i2eGetMail        = iiGetMailIIEX;		pB->i2eEnableMailIrq  = iiEnableMailIrqIIEX;		pB->i2eWriteMask      = iiWriteMaskIIEX;		break;	default:		COMPLETE(pB, I2EE_INCONSIST);	}	// Initialize state information.	pB->i2eState = II_STATE_READY;   // Ready to load loadware.	// Some Final cleanup:	// For some boards, the bootstrap firmware may perform some sort of test	// resulting in a stray character pending in the incoming mailbox. If one is	// there, it should be read and discarded, especially since for the standard	// firmware, it's the mailbox that interrupts the host.	pB->i2eStartMail = iiGetMail(pB);	// Throw it away and clear the mailbox structure element	pB->i2eStartMail = NO_MAIL_HERE;	// Everything is ok now, return with good status/	pB->i2eValid = I2E_MAGIC;	COMPLETE(pB, I2EE_GOOD);}//=======================================================// Delay Routines//// iiDelayIO// iiNop//=======================================================static voidii2DelayWakeup(unsigned long id){	wake_up_interruptible ( &pDelayWait );}//******************************************************************************// Function:   ii2DelayTimer(mseconds)// Parameters: mseconds - number of milliseconds to delay//// Returns:    Nothing//// Description://// This routine delays for approximately mseconds milliseconds and is intended// to be called indirectly through i2Delay field in i2eBordStr. It uses the// Linux timer_list mechanism.//// The Linux timers use a unit called "jiffies" which are 10mS in the Intel// architecture. This function rounds the delay period up to the next "jiffy".// In the Alpha architecture the "jiffy" is 1mS, but this driver is not intended// for Alpha platforms at this time.////******************************************************************************static voidii2DelayTimer(unsigned int mseconds){	wait_queue_t wait;	init_waitqueue_entry(&wait, current);	init_timer ( pDelayTimer );	add_wait_queue(&pDelayWait, &wait);	set_current_state( TASK_INTERRUPTIBLE );	pDelayTimer->expires  = jiffies + ( mseconds + 9 ) / 10;	pDelayTimer->function = ii2DelayWakeup;	pDelayTimer->data     = 0;	add_timer ( pDelayTimer );	schedule();	set_current_state( TASK_RUNNING );	remove_wait_queue(&pDelayWait, &wait);	del_timer ( pDelayTimer );}#if 0//static void ii2DelayIO(unsigned int);//******************************************************************************// !!! Not Used, this is DOS crap, some of you young folks may be interested in//     in how things were done in the stone age of caculating machines       !!!// Function:   ii2DelayIO(mseconds)// Parameters: mseconds - number of milliseconds to delay//// Returns:    Nothing//// Description://// This routine delays for approximately mseconds milliseconds and is intended// to be called indirectly through i2Delay field in i2eBordStr. It is intended// for use where a clock-based function is impossible: for example, DOS drivers.//// This function uses the IN instruction to place bounds on the timing and// assumes that ii2Safe has been set. This is because I/O instructions are not// subject to caching and will therefore take a certain minimum time. To ensure// the delay is at least long enough on fast machines, it is based on some// fastest-case calculations.  On slower machines this may cause VERY long// delays. (3 x fastest case). In the fastest case, everything is cached except// the I/O instruction itself.//// Timing calculations:// The fastest bus speed for I/O operations is likely to be 10 MHz. The I/O// operation in question is a byte operation to an odd address. For 8-bit// operations, the architecture generally enforces two wait states. At 10 MHz, a// single cycle time is 100nS. A read operation at two wait states takes 6// cycles for a total time of 600nS. Therefore approximately 1666 iterations// would be required to generate a single millisecond delay. The worst// (reasonable) case would be an 8MHz system with no cacheing. In this case, the// I/O instruction would take 125nS x 6 cyles = 750 nS. More importantly, code// fetch of other instructions in the loop would take time (zero wait states,// however) and would be hard to estimate. This is minimized by using in-line// assembler for the in inner loop of IN instructions. This consists of just a// few bytes. So we'll guess about four code fetches per loop. Each code fetch// should take four cycles, so we have 125nS * 8 = 1000nS. Worst case then is// that what should have taken 1 mS takes instead 1666 * (1750) = 2.9 mS.//// So much for theoretical timings: results using 1666 value on some actual// machines:// IBM      286      6MHz     3.15 mS// Zenith   386      33MHz    2.45 mS// (brandX) 386      33MHz    1.90 mS  (has cache)// (brandY) 486      33MHz    2.35 mS// NCR      486      ??       1.65 mS (microchannel)//// For most machines, it is probably safe to scale this number back (remember,// for robust operation use an actual timed delay if possible), so we are using// a value of 1190. This yields 1.17 mS for the fastest machine in our sample,// 1.75 mS for typical 386 machines, and 2.25 mS the absolute slowest machine.//// 1/29/93:// The above timings are too slow. Actual cycle times might be faster. ISA cycle// times could approach 500 nS, and ...// The IBM model 77 being microchannel has no wait states for 8-bit reads and// seems to be accessing the I/O at 440 nS per access (from start of one to// start of next). This would imply we need 1000/.440 = 2272 iterations to// guarantee we are fast enough. In actual testing, we see that 2 * 1190 are in// fact enough. For diagnostics, we keep the level at 1190, but developers note// this needs tuning.//// Safe assumption:  2270 i/o reads = 1 millisecond////******************************************************************************static int ii2DelValue = 1190;  // See timing calculations below						// 1666 for fastest theoretical machine						// 1190 safe for most fast 386 machines						// 1000 for fastest machine tested here						//  540 (sic) for AT286/6Mhzstatic voidii2DelayIO(unsigned int mseconds){	if (!ii2Safe) 		return;   /* Do nothing if this variable uninitialized */	while(mseconds--) {		int i = ii2DelValue;		while ( i-- ) {			INB ( ii2Safe );		}	}}#endif //******************************************************************************// Function:   ii2Nop()// Parameters: None//// Returns:    Nothing//// Description://// iiInitialize will set i2eDelay to this if the delay parameter is NULL. This// saves checking for a NULL pointer at every call.//******************************************************************************static voidii2Nop(void){	return;	// no mystery here}//=======================================================// Routines which are available in 8/16-bit versions, or// in different fifo styles. These are ALL called// indirectly through the board structure.//=======================================================//******************************************************************************// Function:   iiWriteBuf16(pB, address, count)// Parameters: pB      - pointer to board structure//             address - address of data to write//             count   - number of data bytes to write//// Returns:    True if everything appears copacetic.//             False if there is any error: the pB->i2eError field has the error//// Description://// Writes 'count' bytes from 'address' to the data fifo specified by the board// structure pointer pB. Should count happen to be odd, an extra pad byte is

⌨️ 快捷键说明

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