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

📄 ep93xx_irda.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Function ep93xx_irda_dma_receive_complete(self, size) * *    Check for complete frame.  Massage as needed and *    put it on the stack if it's "good". * */static int ep93xx_irda_dma_receive_complete(struct ep93xx_irda_cb *self, 		unsigned int frameSize){    struct st_fifo *st_fifo;    struct sk_buff *skb;    int iDMAh, iBufID, iTotalBytes;	        EP93XX_DEBUG(2, "%s(), ---------------- Start -----------------\n",         __FUNCTION__);        /*     * Stop DMA.     */      SetDMA(self, self->direction, FALSE);        st_fifo = &self->st_fifo;		    iDMAh = self->iDMAh[DMA_MFIR_RX];    if(ep93xx_dma_remove_buffer(iDMAh, &iBufID) == -EINVAL)    {	EP93XX_DEBUG(1, "DMARx failed to remove buffer?\n");    }       if(ep93xx_dma_get_position(iDMAh, &iBufID, &iTotalBytes, 0) == -EINVAL)    {        /*         * This can currently only happen if the handle is bad.         */	ERROR("%s(), ********* DMA_GET_POS FAILED *********\n",             __FUNCTION__);    }    /*     * Flush the channel.     */    ep93xx_dma_flush(iDMAh);        if((frameSize > 2047) && (self->speed > 115200))    {        /*         * By IrDA protocol, this is invalid.         */	EP93XX_DEBUG(1, "%s(), *******Rx frame size > 2047!****** \n", 			__FUNCTION__);            self->stats.rx_errors++;	self->rx_buff.data += frameSize;        return(FALSE);    }    skb = dev_alloc_skb(frameSize+1);    if(skb == NULL)      {	WARNING("%s(), memory squeeze, dropping frame.\n",                __FUNCTION__);   	self->stats.rx_dropped++;  	return(FALSE);    }	    /*      * Make sure IP header gets aligned      */    skb_reserve(skb, 1);     /*      * HW does not stuff CRC32 into RX buffer.     */     skb_put(skb, frameSize);     memcpy(skb->data, self->rx_buff.data, frameSize);     /*       * Move to next frame       */     self->rx_buff.data += frameSize;     self->stats.rx_bytes += frameSize;     self->stats.rx_packets++;     skb->dev = self->netdev;     skb->mac.raw  = skb->data;     skb->protocol = htons(ETH_P_IRDA);     netif_rx(skb);            //mdelay(5);     EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n",         __FUNCTION__);	     return(TRUE);}/* * Function ep93xx_irda_net_ioctl(dev, rq, cmd) * *    Process IOCTL commands for this device. * */static int ep93xx_irda_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd){     struct if_irda_req *irq = (struct if_irda_req *) rq;    struct ep93xx_irda_cb *self;    unsigned long ulFlags;    int iRet = 0;	    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n",         __FUNCTION__);	    ASSERT(dev != NULL, return -1;);    self = dev->priv;    ASSERT(self != NULL, return -1;);    EP93XX_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);	    switch(cmd)     {	        case SIOCSBANDWIDTH:             {                /* Set bandwidth */	        EP93XX_DEBUG(1, "%s(), SIOCSBANDWIDTH\n", __FUNCTION__);	        /* Root only */	        if (!capable(CAP_NET_ADMIN))               	{		        return(-EPERM);               	}	        ep93xx_irda_change_speed(self, irq->ifr_baudrate);			        break;            }	    case SIOCSMEDIABUSY:             {                /* Set media busy */	        EP93XX_DEBUG(2, "%s(), SIOCSMEDIABUSY\n", __FUNCTION__);	        if (!capable(CAP_NET_ADMIN))                {		        return(-EPERM);                }	        irda_device_set_media_busy(self->netdev, TRUE);	        break;            }	    case SIOCGRECEIVING:             {                /* Check if we are receiving right now */	        EP93XX_DEBUG(2, "%s(), SIOCGRECEIVING - %d\n", __FUNCTION__, 					self->speed);	        /* Is it really needed ? And what about spinlock ? */	        save_flags(ulFlags);	        cli();		        irq->ifr_receiving = ep93xx_irda_is_receiving(self);	        restore_flags(ulFlags);	        break;            }	    default:            {		        iRet = -EOPNOTSUPP;            }    }    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n",         __FUNCTION__);		    return(iRet);}/* * Function ep93xx_irda_is_receiving(self) * *    Return TRUE is we are currently receiving a frame * */static int ep93xx_irda_is_receiving(struct ep93xx_irda_cb *self){    unsigned long ulFlags;    int iStatus = FALSE;	    EP93XX_DEBUG(2, "%s(), ---------------- Start -----------------\n",         __FUNCTION__);	    ASSERT(self != NULL, return FALSE;);    spin_lock_irqsave(&self->lock, ulFlags);    if(self->speed > 115200)     {    	EP93XX_DEBUG(1, "%s(), check MFIR.\n", __FUNCTION__); 	if((inl(IrFlag) & IrFLAG_RXINFRM) != 0) 			{		/* 		 * We are receiving something 		 */		EP93XX_DEBUG(1, "%s(), We are receiving something\n",                 		__FUNCTION__);		iStatus = TRUE;	}    }     else    { 	iStatus = (self->rx_buff.state != OUTSIDE_FRAME);    }	    spin_unlock_irqrestore(&self->lock, ulFlags);    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n",         __FUNCTION__);	    return(iStatus);}/* * Function ep93xx_irda_net_get_stats(dev) * *    Return stats structure. * */static struct net_device_stats *ep93xx_irda_net_get_stats(struct net_device *dev){    struct ep93xx_irda_cb *self = (struct ep93xx_irda_cb *) dev->priv;	    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n",         __FUNCTION__);		    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n",         __FUNCTION__);	    return(&self->stats);}#ifdef POWER_SAVING/* * Function ep93xx_irda_suspend(self) * *    Called by the OS to indicate the system *    is being suspended for PM.  Shut our hardware *    down. * */static void ep93xx_irda_suspend(struct ep93xx_irda_cb *self){    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n",         __FUNCTION__);	    MESSAGE("%s, Suspending\n", driver_name);    if(self->suspended)    {	return;    }    ep93xx_irda_net_close(self->netdev);    self->suspended = 1;	    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n",         __FUNCTION__);	}/* * Function ep93xx_irda_wakeup(self) * *    Called by the OS to indicate a resume from suspend is taking place. *    Awaken the hardware.  * */static void ep93xx_irda_wakeup(struct ep93xx_irda_cb *self){    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n",         __FUNCTION__);	    if(!self->suspended)    {	return;    }	    ep93xx_irda_net_open(self->netdev);	    MESSAGE("%s, Waking up\n", driver_name);    self->suspended = 0;	    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n",         __FUNCTION__);}/* * Function ep93xx_irda_pmproc(dev, rqst, data) * * Registered power management callback procedure. * */static int ep93xx_irda_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data){    struct ep93xx_irda_cb *self = (struct ep93xx_irda_cb*) dev->data;            EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n",             __FUNCTION__);	    if(self)     {	    switch(rqst)             {		    case PM_SUSPEND:                        {                            ep93xx_irda_suspend(self);                            break;                        }                    case PM_RESUME:                        {                            ep93xx_irda_wakeup(self);                            break;                        }            }    }            EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n",             __FUNCTION__);	            return(0);}#endif/* * Function SetInterrupts * *    Sets interrupts on/off based on speed and boolean. *    A boolean value of TRUE turns on interrupts for  *    the hardware that manages that IR speed.  FALSE turns them off. * */static void SetInterrupts(struct ep93xx_irda_cb *self, unsigned char enable){	    unsigned char ucRegVal = 0, ucRegMask = 0;    unsigned long ulRegAddr, ulRegAddr2;    EP93XX_DEBUG(2, "%s(), ----------- Start -----------\n",         __FUNCTION__);	    EP93XX_DEBUG(2, "%s(), IRQs enable = %d, speed = %d\n", __FUNCTION__, 		    enable, self->speed);        if(self->speed <= 115200)    {        /* Action on IRQs in SIR mode */        ulRegAddr = UART2CR;        ucRegVal = inl(ulRegAddr);	 	if(self->direction & DIR_TX)	{		ucRegMask |= U2CR_TxIrq;	} 		if(self->direction & DIR_RX)	{		ucRegMask |= U2CR_RxIrq;	}	        if(enable)        {	    ucRegVal &= (char)~(U2CR_RxIrq|U2CR_TxIrq);	            ucRegVal |= (char)(ucRegMask);        }        else        {            ucRegVal &= (char)~(ucRegMask);        }    }    else    {	ucRegMask = 0;        if(self->speed <= 1152000)        {            /*             * Action on IRQs in MIR mode              */            ulRegAddr = MIMR;	    ulRegAddr2 = MISR;        }        else        {            /*              * Action on IRQs in FIR mode                  */                 ulRegAddr = FIMR;	    ulRegAddr2 = FISR;        }	if(self->direction & DIR_TX)	{		ucRegMask |= (MFIMR_TXABORT|MFIMR_TXFC);	}	if(self->direction & DIR_RX)	{		ucRegMask |= (MFIMR_RXFL|MFIMR_RXFC);	}	        /*         * Bit mask is the same for MIR/FIR.         */        if(enable)        {            ucRegVal |= (char)(ucRegMask);	    /*	     * Clear sticky bits before turning on IRQs	     */	    outl(MFISR_TXFC|MFISR_TXFABORT|MFISR_RXIL|MFISR_RXFL, ulRegAddr2);	    inl(ulRegAddr2);	    inl(IrRIB);        }        else        {            /*             * M/FIR IRQ registers only have IRQ related bits, safe             * to blast them therefore.             */            ucRegVal = 0;        }    }    outl(ucRegVal, ulRegAddr);          EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n",         __FUNCTION__);	}static void SetIR_Transmit(unsigned char ucEnable){	unsigned long ulRegVal;		ulRegVal = inb(IrCtrl);	if(ucEnable)	{		if(ulRegVal & IrCONTROL_TXON)		{			return;		}		else		{			outb(ulRegVal|IrCONTROL_TXON, IrCtrl);		}	}	else	{		if(!(ulRegVal & IrCONTROL_TXON))		{			return;		}		else		{			outb(ulRegVal&~(IrCONTROL_TXON), IrCtrl);		}	}}/* * Function SetIR_Receive() * * 	Enables OR Disables RX & RXRP in IrCtrl based on * 	supplied boolean. */static voidSetIR_Receive(unsigned char ucEnable){	unsigned long ulRegVal;	ulRegVal = inb(IrCtrl);	if(ucEnable)	{		if((ulRegVal & (IrCONTROL_RXON|IrCONTROL_RXRP)) == 				(IrCONTROL_RXON|IrCONTROL_RXRP))		{			return;		}		else		{			outb(ulRegVal|IrCONTROL_RXON|IrCONTROL_RXRP, IrCtrl);		}	}	else	{		if(!(ulRegVal & (IrCONTROL_RXON & IrCONTROL_RXRP)))		{			return;		}		else		{			outb(ulRegVal&~(IrCONTROL_RXON|IrCONTROL_RXRP), 					IrCtrl);		}	}}/* * Function SetDMA() * *    Enables or disables DMA  capability for current speed. *    'enable' parameter determines action. Direction  *    determines tx and/or rx DMA. * */static voidSetDMA(struct ep93xx_irda_cb *self, unsigned char direction,          unsigned char enable){    int iRegVal, iDMARegVal;         if(self->speed <= 115200)    {	/*	 * SIR section.  No DMA for SIR at this time.	 */        if(direction == DIR_RX)	{	}	else	{	}	    }    else    {    	 /*	  * MFIR Section	  */   	 /*	  * Read in current value.	  */	 iRegVal = iDMARegVal = inb(IrDMACR);      	 

⌨️ 快捷键说明

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