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

📄 8253xutl.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (quot <= 0x400)   {	  /* quot = [1, 0x400]  -> (quot << 5) != 0 */	  *truebaudp = ROUND_DIV(clk_speed, ((unsigned long) quot << 5));	  quot--;	  	  ccr2tmp = SAB82532_CCR2_BDF;	  if ((quot & 0x200) != 0) 	  {		  ccr2tmp |= SAB82532_CCR2_BR9;	  }	  if ((quot & 0x100) != 0) 	  {		  ccr2tmp |=SAB82532_CCR2_BR8;	  }	  	  *ccr2 = ccr2tmp | (*ccr2 & ~(SAB82532_CCR2_BDF|SAB82532_CCR2_BR8|SAB82532_CCR2_BR9));	  *bgr = (unsigned char) quot;  }  else   {			/* the baud rate is too small. */	  return FALSE;  }    return TRUE;}/*************************************************************************** * sab_baud:      Function to compute the best register value to achieve *                a given baudrate. *                 * *     Parameters   :  *                  port:    The port being used  (in only) *                  encbaud: 2* the baudrate. We use the *                           double value so as to support 134.5 (in only) *                  bgr      Value of reg BGR for baudrate(output) *                  ccr2     Value of reg CCR2 for baudrate (output) *                  ccr4     Value of reg CCR4 for baudrate (output) *                  truebaud The actual baudrate achieved (output). * * *     Return value : Return TRUE if the vaudrate can be set, FALSE otherwise  * *     Prerequisite : The various ports must have been initialized * *     Remark       : Stolen from the Aurora ase driver. * *     Author       : fw * *     Revision     : Oct 9 2000, creation ***************************************************************************/unsigned int sab8253x_baud(sab_port_t *port, unsigned long encbaud,	      unsigned char *bgr, unsigned char *ccr2,	      unsigned char *ccr4, unsigned long *truebaudp){	unsigned char	 bgr_std, bgr_enh, ccr2_std, ccr2_enh, ccr4_enh;	unsigned int		 ok_std, ok_enh;	unsigned long	 truebaud_std, truebaud_enh, truebaud,clkspeed;		bgr_std = bgr_enh = 0;	ccr2_std = ccr2_enh = 0;	ccr4_enh = 0;		/*	 * the port/chip/board structure will tell us:	 *  1) clock speed	 *  2) chip revision (to figure out if the enhanced method is	 *     available.	 */		clkspeed = port->chip->c_cim ? port->chip->c_cim->ci_clkspeed :  port->board->b_clkspeed;	#ifdef NODEBUGGING	printk("With clk speed %ld, baud rate = %ld\n",clkspeed, encbaud);#endif		ok_std = sab8253x_baudstd(encbaud, clkspeed, &bgr_std,				  &ccr2_std, &truebaud_std);#ifdef NODEBUGGING	printk("Std gives bgr = 0x%x, ccr2=0x%x for speed %ld\n",bgr_std,ccr2_std,truebaud_std);#endif	if(port->chip->c_revision >= SAB82532_VSTR_VN_3_2) 	{		ok_enh = sab8253x_baudenh(encbaud, clkspeed,					  &bgr_enh, &ccr2_enh, &truebaud_enh);#ifdef NODEBUGGING		printk("Enh gives bgr = 0x%x, ccr2=0x%x for speed %ld\n",bgr_enh,ccr2_enh,truebaud_enh);#endif	} 	else 		ok_enh = FALSE;		/*	 * Did both methods return values?	 */	if (ok_std && ok_enh) 	{		/*		 * Find the closest of the two.		 */		if (ABSDIF((truebaud_enh<<1), encbaud) <		    ABSDIF((truebaud_std<<1), encbaud)) 		{			ok_std = FALSE;		}		else 		{			ok_enh = FALSE;		}	}		/*	 * Now return the values.	 */		if (ok_std || ok_enh) 	{		truebaud = ok_std ? truebaud_std : truebaud_enh;				/*		 * If the true baud rate is off by more than 5%, then		 *  we don't support it.		 */		if (ROUND_DIV(ABSDIF((truebaud<<1), encbaud), encbaud) != 0) 		{			/*			 * We're not even in the right ballpark.  This			 *  test is here to deal with overflow conditions.			 */			return FALSE;		}		else if (ROUND_DIV(ABSDIF((truebaud<<1), encbaud) * 100,				   encbaud) >= 5) 		{			return FALSE;		}				*truebaudp = truebaud;				if (ok_enh) 		{			*ccr4 |= SAB82532_CCR4_EBRG;			*ccr2 = ccr2_enh;			*bgr = bgr_enh;#ifdef DEBUGGING			printk("Enhanced Baud at %ld, ccr4 = 0x%x, ccr2 = 9x%x, bgr = 0x%x\n",			       truebaud,*ccr4,*ccr2,*bgr);#endif		} 		else 		{			*ccr4 &= ~SAB82532_CCR4_EBRG;			*ccr2 = ccr2_std;			*bgr = bgr_std;#ifdef DEBUGGING			printk("Standard Baud at %ld, ccr4 = 0x%x, ccr2 = 9x%x, bgr = 0x%x\n",			       truebaud,*ccr4,*ccr2,*bgr);#endif		}				return TRUE;	}	else 	{		return FALSE;	}}int Sab8253xCountTransmit(SAB_PORT *port){	register RING_DESCRIPTOR *rd;	register int total;	register int count;	unsigned long flags;	RING_DESCRIPTOR *start;		if(port->sabnext2.transmit == NULL)	{		return 0;	}		save_flags(flags);	cli();	rd = port->sabnext2.transmit;	start = rd;	total = 0;	while(1)	{		count = rd->Count;		if((count & OWNER) == OWN_DRIVER)		{			break;		}		total += (count & ~OWNER);		if(rd->sendcrc)		{			total += (4 - rd->crcindex);		}		rd = rd->VNext;		if(rd == start)		{			break;		}	}	restore_flags(flags);	return total;}int Sab8253xCountTransmitDescriptors(SAB_PORT *port){	register RING_DESCRIPTOR *rd;	register int total;	register int count;	unsigned long flags;	RING_DESCRIPTOR *start;		if(port->sabnext2.transmit == NULL)	{		return 0;	}		save_flags(flags);	cli();	rd = port->sabnext2.transmit;	start = rd;	total = 0;	while(1)	{		count = rd->Count;		if((count & OWNER) == OWN_DRIVER)		{			break;		}		++total;		rd = rd->VNext;		if(rd == start)		{			break;		}	}	restore_flags(flags);	return total;}int getccr0configS(struct sab_port *port){	return port->ccontrol.ccr0;}int getccr1configS(struct sab_port *port){	return port->ccontrol.ccr1;}int getccr2configS(struct sab_port *port){	return port->ccontrol.ccr2;}int getccr3configS(struct sab_port *port){	return port->ccontrol.ccr3;}int getccr4configS(struct sab_port *port){	return port->ccontrol.ccr4;}int getrlcrconfigS(struct sab_port *port){	return port->ccontrol.rlcr;}int getmodeS(struct sab_port *port){	return port->ccontrol.mode;}void sab8253x_init_lineS(struct sab_port *port){	unsigned char stat;		if(port->chip->c_cim)	{		if(port->chip->c_cim->ci_type == CIM_SP502)		{			aura_sp502_program(port, SP502_OFF_MODE);		}	}	/*	 * Wait for any commands or immediate characters	 */	sab8253x_cec_wait(port);#if 0	sab8253x_tec_wait(port);	/* I have to think about this one					 * should I assume the line was					 * previously in async mode*/#endif		/*	 * Clear the FIFO buffers.	 */		WRITEB(port, cmdr, SAB82532_CMDR_RHR);	sab8253x_cec_wait(port);	WRITEB(port,cmdr,SAB82532_CMDR_XRES);			/*	 * Clear the interrupt registers.	 */	stat = READB(port, isr0);	/* acks ints */	stat = READB(port, isr1);		/*	 * Now, initialize the UART 	 */	WRITEB(port, ccr0, 0);	  /* power-down */	WRITEB(port, ccr0, getccr0configS(port));	WRITEB(port, ccr1, getccr1configS(port));	WRITEB(port, ccr2, getccr2configS(port));	WRITEB(port, ccr3, getccr3configS(port));	WRITEB(port, ccr4, getccr4configS(port));	/* 32 byte receive fifo */	WRITEB(port, mode, getmodeS(port));	WRITEB(port, tic /* really rlcr */, getrlcrconfigS(port));	/* power-up */		switch(port->ccontrol.ccr4 & SAB82532_CCR4_RF02)	{	case SAB82532_CCR4_RF32:		port->recv_fifo_size = 32;		break;	case SAB82532_CCR4_RF16:		port->recv_fifo_size = 16;		break;	case SAB82532_CCR4_RF04:		port->recv_fifo_size = 4;		break;	case SAB82532_CCR4_RF02:		port->recv_fifo_size = 2;		break;	default:		port->recv_fifo_size = 32;		port->ccontrol.ccr4 &= ~SAB82532_CCR4_RF02;		break;	}		if(port->ccontrol.ccr2 & SAB82532_CCR2_TOE)	{		RAISE(port, txclkdir);	}	else	{		LOWER(port, txclkdir);	}		SET_REG_BIT(port,ccr0,SAB82532_CCR0_PU);	if(port->chip->c_cim)	{		if(port->chip->c_cim->ci_type == CIM_SP502)		{			aura_sp502_program(port, port->sigmode);		}	}}/* frees up all skbuffs currently *//* held by driver */void Sab8253xFreeAllFreeListSKBUFFS(SAB_PORT* priv) /* empty the skbuffer list *//* either on failed open *//* or on close*/{	struct sk_buff* skb;		if(priv->sab8253xbuflist == NULL)	{		return;	}		DEBUGPRINT((KERN_ALERT "sab8253x: freeing %i skbuffs.\n", 		    skb_queue_len(priv->sab8253xbuflist)));		while(skb_queue_len(priv->sab8253xbuflist) > 0)	{		skb = skb_dequeue(priv->sab8253xbuflist);		dev_kfree_skb_any(skb);	}	kfree(priv->sab8253xbuflist);	priv->sab8253xbuflist = NULL;}int Sab8253xSetUpLists(SAB_PORT *priv){	if(priv->sab8253xbuflist)	{		if(priv->sab8253xc_rcvbuflist)		{			return 0;		}		else		{			return -1;		}		return 0;	}	else if(priv->sab8253xc_rcvbuflist)	{		return -1;	}		priv->sab8253xbuflist = (struct sk_buff_head*) kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);	if(priv->sab8253xbuflist == NULL)	{		return -1;	}	priv->sab8253xc_rcvbuflist = (struct sk_buff_head*) kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);  	if(priv->sab8253xc_rcvbuflist == NULL)	{		kfree(priv->sab8253xbuflist);		return -1;	}	skb_queue_head_init(priv->sab8253xbuflist);	skb_queue_head_init(priv->sab8253xc_rcvbuflist);	return 0;}/* sets up transmit ring and one receive sk_buff *//* set up transmit and receive   sk_buff control structures */int Sab8253xInitDescriptors2(SAB_PORT *priv, int listsize, int rbufsize){	RING_DESCRIPTOR *desc;	RING_DESCRIPTOR *xdesc;		if(priv->dcontrol2.transmit != NULL)			{		if(priv->dcontrol2.receive != NULL)		{			return 0;		}		return -1;	}	else if(priv->dcontrol2.receive != NULL)	{		return -1;	}		priv->dcontrol2.transmit = (RING_DESCRIPTOR*) 		kmalloc(sizeof(RING_DESCRIPTOR) * listsize, GFP_KERNEL);	/* dcontrol2 is an historical	   artifact from when the code	   talked to an intelligent controller */	if(priv->dcontrol2.transmit == NULL)	{		return -1;	}		priv->dcontrol2.receive = (RING_DESCRIPTOR*)		kmalloc(sizeof(RING_DESCRIPTOR), GFP_KERNEL); /* only one receive sk_buffer */	if(priv->dcontrol2.receive == NULL)	{		kfree(priv->dcontrol2.transmit);		priv->dcontrol2.transmit = NULL;		return -1;	}		for(xdesc = priv->dcontrol2.transmit; 

⌨️ 快捷键说明

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