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

📄 i2ellis.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
/*********************************************************************************   (c) 1998 by Computone Corporation************************************************************************************   PACKAGE:     Linux tty Device Driver for IntelliPort family of multiport*                serial I/O controllers.**   DESCRIPTION: Low-level interface code for the device driver*                (This is included source code, not a separate compilation*                module.)********************************************************************************///---------------------------------------------// Function declarations private to this module//---------------------------------------------// Functions called only indirectly through i2eBordStr entries.static int iiWriteBuf16(i2eBordStrPtr, unsigned char *, int);static int iiWriteBuf8(i2eBordStrPtr, unsigned char *, int);static int iiReadBuf16(i2eBordStrPtr, unsigned char *, int);static int iiReadBuf8(i2eBordStrPtr, unsigned char *, int);static unsigned short iiReadWord16(i2eBordStrPtr);static unsigned short iiReadWord8(i2eBordStrPtr);static void iiWriteWord16(i2eBordStrPtr, unsigned short);static void iiWriteWord8(i2eBordStrPtr, unsigned short);static int iiWaitForTxEmptyII(i2eBordStrPtr, int);static int iiWaitForTxEmptyIIEX(i2eBordStrPtr, int);static int iiTxMailEmptyII(i2eBordStrPtr);static int iiTxMailEmptyIIEX(i2eBordStrPtr);static int iiTrySendMailII(i2eBordStrPtr, unsigned char);static int iiTrySendMailIIEX(i2eBordStrPtr, unsigned char);static unsigned short iiGetMailII(i2eBordStrPtr);static unsigned short iiGetMailIIEX(i2eBordStrPtr);static void iiEnableMailIrqII(i2eBordStrPtr);static void iiEnableMailIrqIIEX(i2eBordStrPtr);static void iiWriteMaskII(i2eBordStrPtr, unsigned char);static void iiWriteMaskIIEX(i2eBordStrPtr, unsigned char);static void ii2DelayTimer(unsigned int);static void ii2DelayWakeup(unsigned long id);static void ii2Nop(void);//***************//* Static Data *//***************static int ii2Safe;         // Safe I/O address for delay routinestatic int iiDelayed;	// Set when the iiResetDelay function is							// called. Cleared when ANY board is reset.static struct timer_list * pDelayTimer;   // Used by iiDelayTimerstatic wait_queue_head_t pDelayWait;    // Used by iiDelayTimerstatic rwlock_t Dl_spinlock;//********//* Code *//********//=======================================================// Initialization Routines//// iiSetAddress// iiReset// iiResetDelay// iiInitialize//=======================================================//******************************************************************************// Function:   iiEllisInit()// Parameters: None//// Returns:    Nothing//// Description://// This routine performs any required initialization of the iiEllis subsystem.////******************************************************************************static voidiiEllisInit(void){	pDelayTimer = kmalloc ( sizeof (struct timer_list), GFP_KERNEL );	init_timer(pDelayTimer);	init_waitqueue_head(&pDelayWait);	LOCK_INIT(&Dl_spinlock);}//******************************************************************************// Function:   iiEllisCleanup()// Parameters: None//// Returns:    Nothing//// Description://// This routine performs any required cleanup of the iiEllis subsystem.////******************************************************************************static voidiiEllisCleanup(void){	kfree(pDelayTimer);}//******************************************************************************// Function:   iiSetAddress(pB, address, delay)// Parameters: pB      - pointer to the board structure//             address - the purported I/O address of the board//             delay   - pointer to the 1-ms delay function to use//                       in this and any future operations to this board//// Returns:    True if everything appears copacetic.//             False if there is any error: the pB->i2eError field has the error//// Description://// This routine (roughly) checks for address validity, sets the i2eValid OK and// sets the state to II_STATE_COLD which means that we haven't even sent a reset// yet.////******************************************************************************static intiiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay ){	// Should any failure occur before init is finished...	pB->i2eValid = I2E_INCOMPLETE;	// Cannot check upper limit except extremely: Might be microchannel	// Address must be on an 8-byte boundary	if ((unsigned int)address <= 0x100		|| (unsigned int)address >= 0xfff8		|| (address & 0x7)		)	{		COMPLETE(pB,I2EE_BADADDR);	}	// Initialize accelerators	pB->i2eBase    = address;	pB->i2eData    = address + FIFO_DATA;	pB->i2eStatus  = address + FIFO_STATUS;	pB->i2ePointer = address + FIFO_PTR;	pB->i2eXMail   = address + FIFO_MAIL;	pB->i2eXMask   = address + FIFO_MASK;	// Initialize i/o address for ii2DelayIO	ii2Safe = address + FIFO_NOP;	// Initialize the delay routine	pB->i2eDelay = ((delay != (delayFunc_t)NULL) ? delay : (delayFunc_t)ii2Nop);	pB->i2eValid = I2E_MAGIC;	pB->i2eState = II_STATE_COLD;	COMPLETE(pB, I2EE_GOOD);}//******************************************************************************// Function:   iiReset(pB)// Parameters: pB - pointer to the board structure//// Returns:    True if everything appears copacetic.//             False if there is any error: the pB->i2eError field has the error//// Description://// Attempts to reset the board (see also i2hw.h). Normally, we would use this to// reset a board immediately after iiSetAddress(), but it is valid to reset a// board from any state, say, in order to change or re-load loadware. (Under// such circumstances, no reason to re-run iiSetAddress(), which is why it is a// separate routine and not included in this routine.////******************************************************************************static intiiReset(i2eBordStrPtr pB){	// Magic number should be set, else even the address is suspect	if (pB->i2eValid != I2E_MAGIC)	{		COMPLETE(pB, I2EE_BADMAGIC);	}	OUTB(pB->i2eBase + FIFO_RESET, 0);  // Any data will do	iiDelay(pB, 50);                    // Pause between resets	OUTB(pB->i2eBase + FIFO_RESET, 0);  // Second reset	// We must wait before even attempting to read anything from the FIFO: the	// board's P.O.S.T may actually attempt to read and write its end of the	// FIFO in order to check flags, loop back (where supported), etc. On	// completion of this testing it would reset the FIFO, and on completion	// of all // P.O.S.T., write the message. We must not mistake data which	// might have been sent for testing as part of the reset message. To	// better utilize time, say, when resetting several boards, we allow the	// delay to be performed externally; in this way the caller can reset 	// several boards, delay a single time, then call the initialization	// routine for all.	pB->i2eState = II_STATE_RESET;	iiDelayed = 0;	// i.e., the delay routine hasn't been called since the most					// recent reset.	// Ensure anything which would have been of use to standard loadware is	// blanked out, since board has now forgotten everything!.	pB->i2eUsingIrq = IRQ_UNDEFINED; // Not set up to use an interrupt yet	pB->i2eWaitingForEmptyFifo = 0;	pB->i2eOutMailWaiting = 0;	pB->i2eChannelPtr = NULL;	pB->i2eChannelCnt = 0;	pB->i2eLeadoffWord[0] = 0;	pB->i2eFifoInInts = 0;	pB->i2eFifoOutInts = 0;	pB->i2eFatalTrap = NULL;	pB->i2eFatal = 0;	COMPLETE(pB, I2EE_GOOD);}//******************************************************************************// Function:   iiResetDelay(pB)// Parameters: pB - pointer to the board structure//// Returns:    True if everything appears copacetic.//             False if there is any error: the pB->i2eError field has the error//// Description://// Using the delay defined in board structure, waits two seconds (for board to// reset).////******************************************************************************static intiiResetDelay(i2eBordStrPtr pB){	if (pB->i2eValid != I2E_MAGIC) {		COMPLETE(pB, I2EE_BADMAGIC);	}	if (pB->i2eState != II_STATE_RESET) {		COMPLETE(pB, I2EE_BADSTATE);	}	iiDelay(pB,2000);       /* Now we wait for two seconds. */	iiDelayed = 1;          /* Delay has been called: ok to initialize */	COMPLETE(pB, I2EE_GOOD);}//******************************************************************************// Function:   iiInitialize(pB)// Parameters: pB - pointer to the board structure//// Returns:    True if everything appears copacetic.//             False if there is any error: the pB->i2eError field has the error//// Description://// Attempts to read the Power-on reset message. Initializes any remaining fields// in the pB structure.//// This should be called as the third step of a process beginning with// iiReset(), then iiResetDelay(). This routine checks to see that the structure// is "valid" and in the reset state, also confirms that the delay routine has// been called since the latest reset (to any board! overly strong!).////******************************************************************************static intiiInitialize(i2eBordStrPtr pB){	int itemp;	unsigned char c;	unsigned short utemp;	unsigned int ilimit;	if (pB->i2eValid != I2E_MAGIC)	{		COMPLETE(pB, I2EE_BADMAGIC);	}	if (pB->i2eState != II_STATE_RESET || !iiDelayed)	{		COMPLETE(pB, I2EE_BADSTATE);	}	// In case there is a failure short of our completely reading the power-up	// message.	pB->i2eValid = I2E_INCOMPLETE;	// Now attempt to read the message.	for (itemp = 0; itemp < sizeof(porStr); itemp++)	{		// We expect the entire message is ready.		if (HAS_NO_INPUT(pB))		{			pB->i2ePomSize = itemp;			COMPLETE(pB, I2EE_PORM_SHORT);		}		pB->i2ePom.c[itemp] = c = BYTE_FROM(pB);		// We check the magic numbers as soon as they are supposed to be read		// (rather than after) to minimize effect of reading something we		// already suspect can't be "us".		if (  (itemp == POR_1_INDEX && c != POR_MAGIC_1) ||				(itemp == POR_2_INDEX && c != POR_MAGIC_2))		{			pB->i2ePomSize = itemp+1;			COMPLETE(pB, I2EE_BADMAGIC);		}	}	pB->i2ePomSize = itemp;	// Ensure that this was all the data...	if (HAS_INPUT(pB))		COMPLETE(pB, I2EE_PORM_LONG);	// For now, we'll fail to initialize if P.O.S.T reports bad chip mapper:	// Implying we will not be able to download any code either:  That's ok: the	// condition is pretty explicit.	if (pB->i2ePom.e.porDiag1 & POR_BAD_MAPPER)	{		COMPLETE(pB, I2EE_POSTERR);	}	// Determine anything which must be done differently depending on the family	// of boards!	switch (pB->i2ePom.e.porID & POR_ID_FAMILY)	{	case POR_ID_FII:  // IntelliPort-II		pB->i2eFifoStyle   = FIFO_II;		pB->i2eFifoSize    = 512;     // 512 bytes, always		pB->i2eDataWidth16 = NO;		pB->i2eMaxIrq = 15;	// Because board cannot tell us it is in an 8-bit							// slot, we do allow it to be done (documentation!)		pB->i2eGoodMap[1] =		pB->i2eGoodMap[2] =		pB->i2eGoodMap[3] =		pB->i2eChannelMap[1] =		pB->i2eChannelMap[2] =		pB->i2eChannelMap[3] = 0;		switch (pB->i2ePom.e.porID & POR_ID_SIZE)		{		case POR_ID_II_4:			pB->i2eGoodMap[0] =			pB->i2eChannelMap[0] = 0x0f;  // four-port			// Since porPorts1 is based on the Hardware ID register, the numbers			// should always be consistent for IntelliPort-II.  Ditto below...			if (pB->i2ePom.e.porPorts1 != 4)			{				COMPLETE(pB, I2EE_INCONSIST);			}			break;		case POR_ID_II_8:		case POR_ID_II_8R:			pB->i2eGoodMap[0] =			pB->i2eChannelMap[0] = 0xff;  // Eight port

⌨️ 快捷键说明

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