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

📄 8253xsyn.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	sab8253x_change_speedS(port);		port->flags |= FLAG8253X_INITIALIZED;	port->receive_chars = sab8253x_receive_charsS;	port->transmit_chars = sab8253x_transmit_charsS;	port->check_status = sab8253x_check_statusS;	port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR |			       SAB82532_ISR1_XDU | SAB82532_ISR1_CSC);	port->check_status_test = (SAB82532_ISR1_CSC);		/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? 0 : SAB82532_ISR0_CDSC));*/			restore_flags(flags);	return 0;	 errout:	restore_flags(flags);	return retval;}static void sab8253x_shutdownS(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);		if (port->xmit_buf) 	{		port->xmit_buf = 0;	}#ifdef XCONFIG_SERIAL_CONSOLE	if (port->is_console) 	{		port->interrupt_mask0 = 			SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |			/*SAB82532_IMR0_TIME |*/			SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;		WRITEB(port,imr0,port->interrupt_mask0);		port->interrupt_mask1 = 			SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |			SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |			SAB82532_IMR1_CSC | SAB82532_IMR1_XON |			SAB82532_IMR1_XPR;		WRITEB(port,imr1,port->interrupt_mask1);		if (port->tty)		{			set_bit(TTY_IO_ERROR, &port->tty->flags);		}		port->flags &= ~FLAG8253X_INITIALIZED;		restore_flags(flags);		return;	}#endif		/* Disable Interrupts */		port->interrupt_mask0 = 0xff;	WRITEB(port, imr0, port->interrupt_mask0);	port->interrupt_mask1 = 0xff;	WRITEB(port, imr1, port->interrupt_mask1);		if (!port->tty || (port->tty->termios->c_cflag & HUPCL)) 	{		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);		if (port->tty)	{		set_bit(TTY_IO_ERROR, &port->tty->flags);	}		port->flags &= ~FLAG8253X_INITIALIZED;	restore_flags(flags);}int sab8253x_writeS(struct tty_struct * tty, int from_user,		    const unsigned char *buf, int count){	struct sab_port *port = (struct sab_port *)tty->driver_data;	struct sk_buff *skb;	int truelength = 0;	int do_queue = 1;		if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_write"))	{		return 0;	}		if(count == 0)	{		return 0;	}		if(port->active2.transmit == NULL)	{		return 0;	}		if((port->active2.transmit->Count & OWNER) == OWN_SAB)	{		sab8253x_start_txS(port);	/* no descriptor slot */		return 0;	}	#ifndef FREEININTERRUPT	skb = port->active2.transmit->HostVaddr; /* current slot value */		if(port->buffergreedy == 0)	/* are we avoiding buffer free's */	{				/* no */		if((skb != NULL) || /* not OWN_SAB from above */		   (port->active2.transmit->crcindex != 0)) 		{			register RING_DESCRIPTOR *freeme;						freeme = port->active2.transmit;			do			{				if((freeme->crcindex == 0) && (freeme->HostVaddr == NULL))				{					break;				}				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 = (RING_DESCRIPTOR*) freeme->VNext;			}			while((freeme->Count & OWNER) != OWN_SAB);		}		skb = NULL;		/* buffer was freed */	}		if(skb != NULL)		/* potentially useful */	{		truelength = (skb->end - skb->head);		if(truelength >= count)		{			skb->data = skb->head; /* this buffer is already queued */			skb->tail = skb->head;			do_queue = 0;		}		else		{			skb_unlink(skb);			dev_kfree_skb_any(skb);			skb = NULL;			port->active2.transmit->HostVaddr = NULL;		}	}	/* in all cases the following is allowed */	port->active2.transmit->sendcrc = 0;	port->active2.transmit->crcindex = 0;#endif		if(skb == NULL)	{		if(port->DoingInterrupt)		{			skb = alloc_skb(count, GFP_ATOMIC);		}		else		{			skb = alloc_skb(count, GFP_KERNEL);		}	}		if(skb == NULL)	{		printk(KERN_ALERT "sab8253xs: no skbuffs available.\n");		return 0;	}	if(from_user)	{		copy_from_user(skb->data, buf, count);	}	else	{		memcpy(skb->data, buf, count);	}	skb->tail = (skb->data + count);	skb->data_len = count;	skb->len = count;		if(do_queue)	{		skb_queue_head(port->sab8253xbuflist, skb);	}		port->active2.transmit->HostVaddr = skb;	port->active2.transmit->sendcrc = 0;	port->active2.transmit->crcindex = 0;	port->active2.transmit->Count = (OWN_SAB|count);	port->active2.transmit = port->active2.transmit->VNext;		sab8253x_start_txS(port);	return count;}void sab8253x_throttleS(struct tty_struct * tty){	struct sab_port *port = (struct sab_port *)tty->driver_data;		if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_throttleS"))	{		return;	}		if (!tty)	{		return;	}		if (I_IXOFF(tty))	{		sab8253x_send_xcharS(tty, STOP_CHAR(tty));	}}void sab8253x_unthrottleS(struct tty_struct * tty){	struct sab_port *port = (struct sab_port *)tty->driver_data;		if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_unthrottle"))	{		return;	}		if (!tty)	{		return;	}		if (I_IXOFF(tty)) 	{		sab8253x_send_xcharS(tty, START_CHAR(tty));	}}void sab8253x_send_xcharS(struct tty_struct *tty, char ch){	struct sab_port *port = (struct sab_port *)tty->driver_data;	unsigned long flags;	int stopped;	int hw_stopped;		if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_send_xcharS"))	{		return;	}		if (!tty)	{		return;	}		if(port->sabnext2.transmit == NULL)	{		return;	}		save_flags(flags); cli();		if((port->sabnext2.transmit->Count & OWNER) == OWN_SAB) /* may overwrite a character								 * -- but putting subsequent								 * XONs or XOFFs later in the								 * stream could cause problems								 * with the XON and XOFF protocol */	{		port->sabnext2.transmit->sendcrc = 1;		port->sabnext2.transmit->crcindex = 3;		port->sabnext2.transmit->crc = (ch << 24); /* LITTLE ENDIAN */		restore_flags(flags);	}	else	{		restore_flags(flags);		sab8253x_writeS(tty, 0, &ch, 1);	}		stopped = tty->stopped;	hw_stopped = tty->hw_stopped;	tty->stopped = 0;	tty->hw_stopped = 0;		sab8253x_start_txS(port);		tty->stopped = stopped;	tty->hw_stopped = hw_stopped;}void sab8253x_breakS(struct tty_struct *tty, int break_state){	struct sab_port *port = (struct sab_port *) tty->driver_data;		if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_breakS"))	{		return;	} /* can't break in sync mode */}void sab8253x_closeS(struct tty_struct *tty, struct file * filp){	struct sab_port *port = (struct sab_port *)tty->driver_data;	unsigned long flags;		MOD_DEC_USE_COUNT;		if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_closeS"))	{		return;	}	if(port->open_type == OPEN_SYNC_NET)	{				/* port->tty field should already be NULL */		return;	}		save_flags(flags); cli();	--(port->count);	if (tty_hung_up_p(filp)) 	{		if(port->count == 0)	/* I think the reason for the weirdness					   relates to freeing of structures in					   the tty driver */		{			port->open_type = OPEN_NOT;		}		else if(port->count < 0)		{			printk(KERN_ALERT "XX20: port->count went negative.\n");			port->count = 0;			port->open_type = OPEN_NOT;		}		restore_flags(flags);		return;	}	#if 0	if ((tty->count == 1) && (port->count != 0)) 	{		/*		 * Uh, oh.  tty->count is 1, which means that the tty		 * structure will be freed.  port->count should always		 * be one in these conditions.  If it's greater than		 * one, we've got real problems, since it means the		 * serial port won't be shutdown.		 */		printk("sab8253x_close: bad serial port count; tty->count is 1,"		       " port->count is %d\n", port->count);		port->count = 0;	}#endif		if (port->count < 0) 	{		printk(KERN_ALERT "sab8253x_close: bad serial port count for ttys%d: %d\n",		       port->line, port->count);		port->count = 0;	}	if (port->count) 	{		restore_flags(flags);		return;	}	port->flags |= FLAG8253X_CLOSING;		/*	 * Save the termios structure, since this port may have	 * separate termios for callout and dialin.	 */	if (port->flags & FLAG8253X_NORMAL_ACTIVE)	{		port->normal_termios = *tty->termios;	}	if (port->flags & FLAG8253X_CALLOUT_ACTIVE)	{		port->callout_termios = *tty->termios;	}	/*	 * Now we wait for the transmit buffer to clear; and we notify 	 * the line discipline to only process XON/XOFF characters.	 */	tty->closing = 1;	if (port->closing_wait != SAB8253X_CLOSING_WAIT_NONE) 	{		tty_wait_until_sent(tty, port->closing_wait);	}		/*	 * At this point we stop accepting input.  To do this, we	 * disable the receive line status interrupts, and turn off	 * the receiver.	 */	#if 0	port->interrupt_mask0 |= SAB82532_IMR0_TCD; /* not needed for sync */#endif	WRITEB(port,imr0,port->interrupt_mask0);		CLEAR_REG_BIT(port, mode, SAB82532_MODE_RAC); /* turn off receiver */		if (port->flags & FLAG8253X_INITIALIZED) 	{		/*		 * Before we drop DTR, make sure the UART transmitter		 * has completely drained; this is especially		 * important if there is a transmit FIFO!		 */		sab8253x_wait_until_sent(tty, port->timeout);	}	sab8253x_shutdownS(port);	Sab8253xCleanUpTransceiveN(port);	if (tty->driver.flush_buffer)	{		tty->driver.flush_buffer(tty);	}	if (tty->ldisc.flush_buffer)	{		tty->ldisc.flush_buffer(tty);	}	tty->closing = 0;	port->event = 0;	port->tty = 0;	if (port->blocked_open) 	{		if (port->close_delay) 		{			current->state = TASK_INTERRUPTIBLE;			schedule_timeout(port->close_delay);		}		wake_up_interruptible(&port->open_wait);	}	port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE|			 FLAG8253X_CLOSING);	wake_up_interruptible(&port->close_wait);	port->open_type = OPEN_NOT;	restore_flags(flags);}void sab8253x_hangupS(struct tty_struct *tty){	struct sab_port * port = (struct sab_port *)tty->driver_data;		if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_hangupS"))	{		return;	}	#ifdef XCONFIG_SERIAL_CONSOLE	if (port->is_console)	{		return;	}#endif		sab8253x_flush_buffer(tty);	if(port)	{		sab8253x_shutdownS(port);		Sab8253xCleanUpTransceiveN(port);		port->event = 0;		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE);		port->tty = 0;		wake_up_interruptible(&port->open_wait);	}}int sab8253x_openS(struct tty_struct *tty, struct file * filp){	struct sab_port	*port;	int retval, line;	int counter;	unsigned long flags;		MOD_INC_USE_COUNT;  	line = MINOR(tty->device) - tty->driver.minor_start;		for(counter = 0, port = AuraPortRoot; 	    (counter < line) && (port != NULL); 	    ++counter)	{		port = port->next;	}		if (!port) 	{		printk(KERN_ALERT "sab8253x_openS: can't find structure for line %d\n",		       line);		return -ENODEV;	}		save_flags(flags);		/* Need to protect port->tty element */	cli();		if(port->tty == 0)	{		port->tty = tty;		tty->flip.tqueue.routine = sab8253x_flush_to_ldiscS;	}	tty->driver_data = port;		if(port->function != FUNCTION_NR)	{		++(port->count);		restore_flags(flags);		return -ENODEV;		/* only allowed if there are no restrictions on the port */	}		if(port->open_type == OPEN_SYNC_NET)	{		port->tty = NULL;	/* Don't bother with open counting here					   but make sure the tty field is NULL*/		restore_flags(flags);		return -EBUSY;	}		restore_flags(flags);		if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_openS"))	{		++(port->count);		return -ENODEV;	}	#ifdef DEBUG_OPEN	printk("sab8253x_open %s%d, count = %d\n", tty->driver.name, port->line,	       port->count);#endif		/*	 * If the port is in the middle of closing, bail out now.	 */	if (tty_hung_up_p(filp) ||	    (port->flags & FLAG8253X_CLOSING)) 	{				if (port->flags & FLAG8253X_CLOSING)		{			interruptible_sleep_on(&port->close_wait);		}#ifdef SERIAL_DO_RESTART		++(port->count);		return ((port->flags & FLAG8253X_HUP_NOTIFY) ?			-EAGAIN : -ERESTARTSYS);#else		++(port->count);		return -EAGAIN;#endif	}		if(port->flags & FLAG8253X_NORMAL_ACTIVE)	{		if(port->open_type == OPEN_ASYNC)		{			++(port->count);			return -EBUSY;	/* can't reopen in sync mode */		}	}	if(port->open_type > OPEN_SYNC) /* can reopen a SYNC_TTY */	{		return -EBUSY;	}	if(Sab8253xSetUpLists(port))	{		++(port->count);		return -ENODEV;	}	if(Sab8253xInitDescriptors2(port, sab8253xs_listsize, sab8253xs_rbufsize))	{		++(port->count);		return -ENODEV;	}		retval = sab8253x_startupS(port);	if (retval)	{		++(port->count);		return retval;		/* does not check channel mode */	}		retval = sab8253x_block_til_ready(tty, filp, port); /* checks channel mode */	++(port->count);	if (retval) 	{		return retval;	}		port->tty = tty;		/* may change here once through the block */	/* because now the port belongs to an new tty */	tty->flip.tqueue.routine = sab8253x_flush_to_ldiscS;	if(Sab8253xSetUpLists(port))	{		return -ENODEV;	}	if(Sab8253xInitDescriptors2(port, sab8253xs_listsize, sab8253xs_rbufsize))	{		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */		/* is the crc32 that is appended */		return -ENODEV;	}		/*	 * Start up serial port	 */	retval = sab8253x_startupS(port); /* in case cu was running the first time					   * the function was called*/	if (retval)	{		return retval;		/* does not check channel mode */	}		if ((port->count == 1) &&	    (port->flags & FLAG8253X_SPLIT_TERMIOS)) 	{		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)		{			*tty->termios = port->normal_termios;		}		else 		{			*tty->termios = port->callout_termios;		}		sab8253x_change_speedS(port);	}		#ifdef XCONFIG_SERIAL_CONSOLE	if (sab8253x_console.cflag && sab8253x_console.index == line) 	{		tty->termios->c_cflag = sab8253x_console.cflag;		sab8253x_console.cflag = 0;		change_speed(port);	}#endif		port->session = current->session;	port->pgrp = current->pgrp;	port->open_type = OPEN_SYNC;	return 0;}

⌨️ 快捷键说明

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