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

📄 8253xutl.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	    xdesc < &priv->dcontrol2.transmit[listsize - 1];	    xdesc = &xdesc[1])	/* set up transmit descriptors */	{		xdesc->HostVaddr = NULL;		xdesc->VNext = &xdesc[1];		xdesc->Count = 0 | OWN_DRIVER;		xdesc->crc = 0;		xdesc->sendcrc = 0;		xdesc->crcindex = 0;	}	xdesc->HostVaddr = NULL;	xdesc->VNext = priv->dcontrol2.transmit; /* circular list */	xdesc->Count = 0 | OWN_DRIVER;	xdesc->crc = 0;	xdesc->sendcrc = 0;	xdesc->crcindex = 0;		desc = priv->dcontrol2.receive; /* only need one descriptor for receive */	desc->HostVaddr = NULL;	desc->VNext = &desc[0];		desc = priv->dcontrol2.receive;	desc->HostVaddr = dev_alloc_skb(rbufsize);	if(desc->HostVaddr == NULL)	{		printk(KERN_ALERT "Unable to allocate skb_buffers (rx 0).\n");		printk(KERN_ALERT "Driver initialization failed.\n");		kfree(priv->dcontrol2.transmit);		kfree(priv->dcontrol2.receive);		priv->dcontrol2.transmit = NULL; /* get rid of descriptor ring */		priv->dcontrol2.receive = NULL; /* get rid of descriptor */		/* probably should do some deallocation of sk_buffs*/		/* but will take place in the open */		return -1;	}	skb_queue_head(priv->sab8253xbuflist, (struct sk_buff*) desc->HostVaddr);	desc->Count = rbufsize|OWN_SAB;	/* belongs to int handler */	desc->crc = 0;	desc->sendcrc = 0;	desc->crcindex = 0;		/* setup the various pointers */	priv->active2 = priv->dcontrol2; /* insert new skbuff */	priv->sabnext2 = priv->dcontrol2; /* transmit from here */		return 0;}/* loads program, waits for PPC *//* and completes initialization*/void Sab8253xCleanUpTransceiveN(SAB_PORT* priv){	Sab8253xFreeAllFreeListSKBUFFS(priv);		Sab8253xFreeAllReceiveListSKBUFFS(priv);		/* these are also cleaned up in the module cleanup routine */	/* should probably only be done here */	if(priv->dcontrol2.receive)	{		kfree(priv->dcontrol2.receive);		priv->dcontrol2.receive = NULL;	}	if(priv->dcontrol2.transmit)	{		kfree(priv->dcontrol2.transmit);		priv->dcontrol2.transmit = NULL;	}	priv->active2 = priv->dcontrol2;	priv->sabnext2 = priv->dcontrol2; }void Sab8253xFreeAllReceiveListSKBUFFS(SAB_PORT* priv) /* empty the skbuffer list *//* either on failed open *//* or on close*/{	struct sk_buff* skb;		if(priv->sab8253xc_rcvbuflist == NULL)	{		return;	}		DEBUGPRINT((KERN_ALERT "sab8253x: freeing %i skbuffs.\n", 		    skb_queue_len(priv->sab8253xc_rcvbuflist)));		while(skb_queue_len(priv->sab8253xc_rcvbuflist) > 0)	{		skb = skb_dequeue(priv->sab8253xc_rcvbuflist);		dev_kfree_skb_any(skb);	}	kfree(priv->sab8253xc_rcvbuflist);	priv->sab8253xc_rcvbuflist = NULL;}/* * This routine is called to set the UART divisor registers to match * the specified baud rate for a serial port. */void sab8253x_change_speedN(struct sab_port *port){	unsigned long	flags;	unsigned char ccr2=0, ccr4=0, ebrg=0;	int bits = 8;	#ifdef DEBUGGING	printk("Change speed!  ");#endif		if(!sab8253x_baud(port, (port->baud)*2, &ebrg, &ccr2, &ccr4, &(port->baud))) 	{		printk("Aurora Warning. baudrate %ld could not be set! Using 115200", port->baud);		port->baud = 115200;		sab8253x_baud(port, (port->baud*2), &ebrg, &ccr2, &ccr4, &(port->baud));	}		if (port->baud)	{		port->timeout = (port->xmit_fifo_size * HZ * bits) / port->baud;		port->cec_timeout = port->tec_timeout >> 2;	}	else	{		port->timeout = 0;		port->cec_timeout = SAB8253X_MAX_CEC_DELAY;	}	port->timeout += HZ / 50;		/* Add .02 seconds of slop */		save_flags(flags); 	cli();	sab8253x_cec_wait(port);		WRITEB(port, bgr, ebrg);	WRITEB(port, ccr2, READB(port, ccr2) & ~(0xc0)); /* clear out current baud rage */	WRITEB(port, ccr2, READB(port, ccr2) | ccr2);	WRITEB(port, ccr4, (READB(port,ccr4) & ~SAB82532_CCR4_EBRG) | ccr4);		if (port->flags & FLAG8253X_CTS_FLOW) 	{		WRITEB(port, mode, READB(port,mode) & ~(SAB82532_MODE_RTS));		port->interrupt_mask1 &= ~(SAB82532_IMR1_CSC);		WRITEB(port, imr1, port->interrupt_mask1);	} 	else 	{		WRITEB(port, mode, READB(port,mode) | SAB82532_MODE_RTS);		port->interrupt_mask1 |= SAB82532_IMR1_CSC;		WRITEB(port, imr1, port->interrupt_mask1);	}	WRITEB(port, mode, READB(port, mode) | SAB82532_MODE_RAC);	restore_flags(flags);}void sab8253x_shutdownN(struct sab_port *port){	unsigned long flags;		if (!(port->flags & FLAG8253X_INITIALIZED))	{		return;	}		save_flags(flags); cli(); /* Disable interrupts */		/*	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq	 * here so the queue might never be waken up	 */	wake_up_interruptible(&port->delta_msr_wait);		/* Disable Interrupts */		port->interrupt_mask0 = 0xff;	WRITEB(port, imr0, port->interrupt_mask0);	port->interrupt_mask1 = 0xff;	WRITEB(port, imr1, port->interrupt_mask1);		LOWER(port,rts);	LOWER(port,dtr);		/* Disable Receiver */		CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC);		/* Power Down */		CLEAR_REG_BIT(port,ccr0,SAB82532_CCR0_PU);		port->flags &= ~FLAG8253X_INITIALIZED;	restore_flags(flags);}int sab8253x_block_til_ready(struct tty_struct *tty, struct file * filp,			     struct sab_port *port){	DECLARE_WAITQUEUE(wait, current);	int retval;	int do_clocal = 0;	unsigned long flags;		/*	 * If the device is in the middle of being closed, then block	 * until it's done, and then try again.	 */	if (tty_hung_up_p(filp) ||	    (port->flags & FLAG8253X_CLOSING)) 	{		if (port->flags & FLAG8253X_CLOSING)		{			interruptible_sleep_on(&port->close_wait); /* finish up previous close */		}#ifdef SERIAL_DO_RESTART		if (port->flags & FLAG8253X_HUP_NOTIFY)		{			return -EAGAIN;		}		else		{			return -ERESTARTSYS;		}#else		return -EAGAIN;#endif	}		/*	 * If this is a callout device, then just make sure the normal	 * device isn't being used.	 */	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) 	{		if (port->flags & FLAG8253X_NORMAL_ACTIVE) 		{			return -EBUSY;	/* async, sync tty or network driver active */		}		if ((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&		    (port->flags & FLAG8253X_SESSION_LOCKOUT) &&		    (port->session != current->session))		{			return -EBUSY;		}		if ((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&		    (port->flags & FLAG8253X_PGRP_LOCKOUT) &&		    (port->pgrp != current->pgrp))		{			return -EBUSY;		}		port->flags |= FLAG8253X_CALLOUT_ACTIVE; /* doing a callout */		return 0;	}		/* sort out async vs sync tty, not call out */	/*	 * If non-blocking mode is set, or the port is not enabled,	 * then make the check up front and then exit.	 */		if ((filp->f_flags & O_NONBLOCK) ||	    (tty->flags & (1 << TTY_IO_ERROR))) 	{		if (port->flags & FLAG8253X_CALLOUT_ACTIVE)		{			return -EBUSY;		}		port->flags |= FLAG8253X_NORMAL_ACTIVE;		return 0;	}		if (port->flags & FLAG8253X_CALLOUT_ACTIVE) 	{		if (port->normal_termios.c_cflag & CLOCAL)		{			do_clocal = 1;		}	} 	else if (tty->termios->c_cflag & CLOCAL)	{		do_clocal = 1;	}		/*	 * Block waiting for the carrier detect and the line to become	 * free (i.e., not in use by the callout).  While we are in	 * this loop, port->count is dropped by one, so that	 * sab8253x_close() knows when to free things.  We restore it upon	 * exit, either normal or abnormal.	 */		/* The port decrement logic is probably */	/* broken -- hence if def'd out -- it does*/	retval = 0;	add_wait_queue(&port->open_wait, &wait); /* starts the wait but does not block here */	port->blocked_open++;	while (1) 	{		save_flags(flags);		cli();		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&		    (tty->termios->c_cflag & CBAUD)) 		{			RAISE(port, dtr);			RAISE(port, rts);	/* maybe not correct for sync */			/*			 * ??? Why changing the mode here? 			 *  port->regs->rw.mode |= SAB82532_MODE_FRTS;			 *  port->regs->rw.mode &= ~(SAB82532_MODE_RTS);			 */		}		restore_flags(flags);		current->state = TASK_INTERRUPTIBLE;		if (tty_hung_up_p(filp) ||		    !(port->flags & FLAG8253X_INITIALIZED)) 		{#ifdef SERIAL_DO_RESTART			if (port->flags & FLAG8253X_HUP_NOTIFY)			{				retval = -EAGAIN;			}			else			{				retval = -ERESTARTSYS;				}#else			retval = -EAGAIN;#endif			break;		}		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&		    !(port->flags & FLAG8253X_CLOSING) &&		    (do_clocal || ISON(port,dcd))) 		{			break;		}#ifdef DEBUG_OPEN		printk("sab8253x_block_til_ready:2 flags = 0x%x\n",port->flags);#endif		if (signal_pending(current)) 		{			retval = -ERESTARTSYS;			break;		}#ifdef DEBUG_OPEN		printk("sab8253x_block_til_ready blocking: ttyS%d, count = %d, flags = %x, clocal = %d, vstr = %02x\n",		       port->line, port->count, port->flags, do_clocal, READB(port,vstr));#endif		schedule();	}	current->state = TASK_RUNNING;	remove_wait_queue(&port->open_wait, &wait);	port->blocked_open--;#ifdef DEBUG_OPEN	printk("sab8253x_block_til_ready after blocking: ttys%d, count = %d\n",	       port->line, port->count);#endif	if (retval)	{		return retval;	}	port->flags |= FLAG8253X_NORMAL_ACTIVE;	return 0;}/* * sab8253x_wait_until_sent() --- wait until the transmitter is empty */void sab8253x_wait_until_sent(struct tty_struct *tty, int timeout){	struct sab_port *port = (struct sab_port *)tty->driver_data;	unsigned long orig_jiffies, char_time;		if (sab8253x_serial_paranoia_check(port,tty->device,"sab8253x_wait_until_sent"))	{		return;	}		orig_jiffies = jiffies;	/*	 * Set the check interval to be 1/5 of the estimated time to	 * send a single character, and make it at least 1.  The check	 * interval should also be less than the timeout.	 * 	 * Note: we have to use pretty tight timings here to satisfy	 * the NIST-PCTS.	 */	char_time = (port->timeout - HZ/50) / port->xmit_fifo_size;	char_time = char_time / 5;	if (char_time == 0)	{		char_time = 1;	}	if (timeout)	{		char_time = MIN(char_time, timeout);	}	while ((Sab8253xCountTransmit(port) > 0) || !port->all_sent) 	{		current->state = TASK_INTERRUPTIBLE;		schedule_timeout(char_time);		if (signal_pending(current))		{			break;		}		if (timeout && time_after(jiffies, orig_jiffies + timeout))		{			break;		}	}}void sab8253x_flush_buffer(struct tty_struct *tty){	struct sab_port *port = (struct sab_port *)tty->driver_data;	unsigned long flags;	register RING_DESCRIPTOR *freeme;		if(sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_flush_buffer"))	{		return;	}		if(port->sabnext2.transmit == NULL)	{		return;	}		save_flags(flags); 	cli();			/* need to turn off ints because mucking				   with sabnext2 */#ifndef FREEININTERRUPT	freeme = port->active2.transmit;	do				/* just go all around */	{		if(freeme->HostVaddr)		{			skb_unlink((struct sk_buff*)freeme->HostVaddr);			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);			freeme->HostVaddr = NULL;		}		freeme->sendcrc = 0;		freeme->crcindex = 0;		freeme->Count = OWN_DRIVER;		freeme = (RING_DESCRIPTOR*) freeme->VNext;	}	while(freeme != port->active2.transmit);#else  /* buffers only from sabnext2.transmit to active2.transmit */	while((port->sabnext2.transmit->Count & OWNER) == OWN_SAB) /* clear out stuff waiting to be transmitted */	{		freeme = port->sabnext2.transmit;		if(freeme->HostVaddr)		{			skb_unlink((struct sk_buff*)freeme->HostVaddr);			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);			freeme->HostVaddr = NULL;		}		freeme->sendcrc = 0;		freeme->crcindex = 0;		freeme->Count = OWN_DRIVER;		port->sabnext2.transmit = freeme->VNext;	}#endif	port->sabnext2.transmit = port->active2.transmit; /* should already be equal to be sure */	sab8253x_cec_wait(port);	WRITEB(port,cmdr,SAB82532_CMDR_XRES);	restore_flags(flags);		wake_up_interruptible(&tty->write_wait); /* wake up tty driver */	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&	    tty->ldisc.write_wakeup)	{		(*tty->ldisc.write_wakeup)(tty);	}}

⌨️ 快捷键说明

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