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

📄 cypress_m8.c

📁 usb driver for 2.6.17
💻 C
📖 第 1 页 / 共 4 页
字号:
/* returns how much space is available in the soft buffer */static int cypress_write_room(struct usb_serial_port *port){	struct cypress_private *priv = usb_get_serial_port_data(port);	int room = 0;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&priv->lock, flags);	room = cypress_buf_space_avail(priv->buf);	spin_unlock_irqrestore(&priv->lock, flags);	dbg("%s - returns %d", __FUNCTION__, room);	return room;}static int cypress_tiocmget (struct usb_serial_port *port, struct file *file){	struct cypress_private *priv = usb_get_serial_port_data(port);	__u8 status, control;	unsigned int result = 0;	unsigned long flags;		dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&priv->lock, flags);	control = priv->line_control;	status = priv->current_status;	spin_unlock_irqrestore(&priv->lock, flags);	result = ((control & CONTROL_DTR)        ? TIOCM_DTR : 0)		| ((control & CONTROL_RTS)       ? TIOCM_RTS : 0)		| ((status & UART_CTS)        ? TIOCM_CTS : 0)		| ((status & UART_DSR)        ? TIOCM_DSR : 0)		| ((status & UART_RI)         ? TIOCM_RI  : 0)		| ((status & UART_CD)         ? TIOCM_CD  : 0);	dbg("%s - result = %x", __FUNCTION__, result);	return result;}static int cypress_tiocmset (struct usb_serial_port *port, struct file *file,			       unsigned int set, unsigned int clear){	struct cypress_private *priv = usb_get_serial_port_data(port);	unsigned long flags;		dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&priv->lock, flags);	if (set & TIOCM_RTS)		priv->line_control |= CONTROL_RTS;	if (set & TIOCM_DTR)		priv->line_control |= CONTROL_DTR;	if (clear & TIOCM_RTS)		priv->line_control &= ~CONTROL_RTS;	if (clear & TIOCM_DTR)		priv->line_control &= ~CONTROL_DTR;	spin_unlock_irqrestore(&priv->lock, flags);	priv->cmd_ctrl = 1;	return cypress_write(port, NULL, 0);}static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg){	struct cypress_private *priv = usb_get_serial_port_data(port);	dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);	switch (cmd) {		case TIOCGSERIAL:			if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) {				return -EFAULT;			}			return (0);			break;		case TIOCSSERIAL:			if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) {				return -EFAULT;			}			/* here we need to call cypress_set_termios to invoke the new settings */			cypress_set_termios(port, &priv->tmp_termios);			return (0);			break;		/* these are called when setting baud rate from gpsd */		case TCGETS:			if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) {				return -EFAULT;			}			return (0);			break;		case TCSETS:			if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) {				return -EFAULT;			}			/* here we need to call cypress_set_termios to invoke the new settings */			cypress_set_termios(port, &priv->tmp_termios);			return (0);			break;		/* This code comes from drivers/char/serial.c and ftdi_sio.c */		case TIOCMIWAIT:			while (priv != NULL) {				interruptible_sleep_on(&priv->delta_msr_wait);				/* see if a signal did it */				if (signal_pending(current))					return -ERESTARTSYS;				else {					char diff = priv->diff_status;					if (diff == 0) {						return -EIO; /* no change => error */					}										/* consume all events */					priv->diff_status = 0;					/* return 0 if caller wanted to know about these bits */					if ( ((arg & TIOCM_RNG) && (diff & UART_RI)) ||					     ((arg & TIOCM_DSR) && (diff & UART_DSR)) ||					     ((arg & TIOCM_CD) && (diff & UART_CD)) ||					     ((arg & TIOCM_CTS) && (diff & UART_CTS)) ) {						return 0;					}					/* otherwise caller can't care less about what happened,					 * and so we continue to wait for more events.					 */				}			}			return 0;			break;		default:			break;	}	dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __FUNCTION__, cmd);	return -ENOIOCTLCMD;} /* cypress_ioctl */static void cypress_set_termios (struct usb_serial_port *port,		struct termios *old_termios){	struct cypress_private *priv = usb_get_serial_port_data(port);	struct tty_struct *tty;	int data_bits, stop_bits, parity_type, parity_enable;	unsigned cflag, iflag, baud_mask;	unsigned long flags;	__u8 oldlines;	int linechange = 0;	dbg("%s - port %d", __FUNCTION__, port->number);	tty = port->tty;	if ((!tty) || (!tty->termios)) {		dbg("%s - no tty structures", __FUNCTION__);		return;	}	spin_lock_irqsave(&priv->lock, flags);	if (!priv->termios_initialized) {		if (priv->chiptype == CT_EARTHMATE) {			*(tty->termios) = tty_std_termios;			tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL |				CLOCAL;		} else if (priv->chiptype == CT_CYPHIDCOM) {			*(tty->termios) = tty_std_termios;			tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |				CLOCAL;		} else if (priv->chiptype == CT_CA42V2) {			*(tty->termios) = tty_std_termios;			tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |				CLOCAL;		}		priv->termios_initialized = 1;	}	spin_unlock_irqrestore(&priv->lock, flags);	cflag = tty->termios->c_cflag;	iflag = tty->termios->c_iflag;	/* check if there are new settings */	if (old_termios) {		if ((cflag != old_termios->c_cflag) ||			(RELEVANT_IFLAG(iflag) !=			 RELEVANT_IFLAG(old_termios->c_iflag))) {			dbg("%s - attempting to set new termios settings",					__FUNCTION__);			/* should make a copy of this in case something goes			 * wrong in the function, we can restore it */			spin_lock_irqsave(&priv->lock, flags);			priv->tmp_termios = *(tty->termios);			spin_unlock_irqrestore(&priv->lock, flags);		} else {			dbg("%s - nothing to do, exiting", __FUNCTION__);			return;		}	} else		return;	/* set number of data bits, parity, stop bits */	/* when parity is disabled the parity type bit is ignored */	/* 1 means 2 stop bits, 0 means 1 stop bit */	stop_bits = cflag & CSTOPB ? 1 : 0;	if (cflag & PARENB) {		parity_enable = 1;		/* 1 means odd parity, 0 means even parity */		parity_type = cflag & PARODD ? 1 : 0;	} else		parity_enable = parity_type = 0;	if (cflag & CSIZE) {		switch (cflag & CSIZE) {			case CS5:				data_bits = 0;				break;			case CS6:				data_bits = 1;				break;			case CS7:				data_bits = 2;				break;			case CS8:				data_bits = 3;				break;			default:				err("%s - CSIZE was set, but not CS5-CS8",						__FUNCTION__);				data_bits = 3;		}	} else		data_bits = 3;	spin_lock_irqsave(&priv->lock, flags);	oldlines = priv->line_control;	if ((cflag & CBAUD) == B0) {		/* drop dtr and rts */		dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__);		baud_mask = B0;		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);	} else {		baud_mask = (cflag & CBAUD);		switch(baud_mask) {			case B300:				dbg("%s - setting baud 300bps", __FUNCTION__);				break;			case B600:				dbg("%s - setting baud 600bps", __FUNCTION__);				break;			case B1200:				dbg("%s - setting baud 1200bps", __FUNCTION__);				break;			case B2400:				dbg("%s - setting baud 2400bps", __FUNCTION__);				break;			case B4800:				dbg("%s - setting baud 4800bps", __FUNCTION__);				break;			case B9600:				dbg("%s - setting baud 9600bps", __FUNCTION__);				break;			case B19200:				dbg("%s - setting baud 19200bps", __FUNCTION__);				break;			case B38400:				dbg("%s - setting baud 38400bps", __FUNCTION__);				break;			case B57600:				dbg("%s - setting baud 57600bps", __FUNCTION__);				break;			case B115200:				dbg("%s - setting baud 115200bps", __FUNCTION__);				break;			default:				dbg("%s - unknown masked baud rate", __FUNCTION__);		}		priv->line_control = (CONTROL_DTR | CONTROL_RTS);	}	spin_unlock_irqrestore(&priv->lock, flags);	dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, "			"%d data_bits (+5)", __FUNCTION__, stop_bits,			parity_enable, parity_type, data_bits);	cypress_serial_control(port, baud_mask, data_bits, stop_bits,			parity_enable, parity_type, 0, CYPRESS_SET_CONFIG);	/* we perform a CYPRESS_GET_CONFIG so that the current settings are	 * filled into the private structure this should confirm that all is	 * working if it returns what we just set */	cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);	/* Here we can define custom tty settings for devices; the main tty	 * termios flag base comes from empeg.c */	spin_lock_irqsave(&priv->lock, flags);	if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) {		dbg("Using custom termios settings for a baud rate of "				"4800bps.");		/* define custom termios settings for NMEA protocol */		tty->termios->c_iflag /* input modes - */			&= ~(IGNBRK  /* disable ignore break */			| BRKINT     /* disable break causes interrupt */			| PARMRK     /* disable mark parity errors */			| ISTRIP     /* disable clear high bit of input char */			| INLCR      /* disable translate NL to CR */			| IGNCR      /* disable ignore CR */			| ICRNL      /* disable translate CR to NL */			| IXON);     /* disable enable XON/XOFF flow control */		tty->termios->c_oflag /* output modes */			&= ~OPOST;    /* disable postprocess output char */		tty->termios->c_lflag /* line discipline modes */			&= ~(ECHO     /* disable echo input characters */			| ECHONL      /* disable echo new line */			| ICANON      /* disable erase, kill, werase, and rprnt					 special characters */			| ISIG        /* disable interrupt, quit, and suspend					 special characters */			| IEXTEN);    /* disable non-POSIX special characters */	} /* CT_CYPHIDCOM: Application should handle this for device */	linechange = (priv->line_control != oldlines);	spin_unlock_irqrestore(&priv->lock, flags);	/* if necessary, set lines */	if (linechange) {		priv->cmd_ctrl = 1;		cypress_write(port, NULL, 0);	}} /* cypress_set_termios *//* returns amount of data still left in soft buffer */static int cypress_chars_in_buffer(struct usb_serial_port *port){	struct cypress_private *priv = usb_get_serial_port_data(port);	int chars = 0;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);		spin_lock_irqsave(&priv->lock, flags);	chars = cypress_buf_data_avail(priv->buf);	spin_unlock_irqrestore(&priv->lock, flags);	dbg("%s - returns %d", __FUNCTION__, chars);	return chars;}static void cypress_throttle (struct usb_serial_port *port){	struct cypress_private *priv = usb_get_serial_port_data(port);	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&priv->lock, flags);	priv->rx_flags = THROTTLED;	spin_unlock_irqrestore(&priv->lock, flags);}static void cypress_unthrottle (struct usb_serial_port *port){	struct cypress_private *priv = usb_get_serial_port_data(port);	int actually_throttled, result;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&priv->lock, flags);	actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED;	priv->rx_flags = 0;	spin_unlock_irqrestore(&priv->lock, flags);	if (actually_throttled) {		port->interrupt_in_urb->dev = port->serial->dev;		result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);		if (result)			dev_err(&port->dev, "%s - failed submitting read urb, "					"error %d\n", __FUNCTION__, result);	}}static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct cypress_private *priv = usb_get_serial_port_data(port);	struct tty_struct *tty;	unsigned char *data = urb->transfer_buffer;	unsigned long flags;	char tty_flag = TTY_NORMAL;	int havedata = 0;	int bytes = 0;	int result;	int i = 0;	dbg("%s - port %d", __FUNCTION__, port->number);

⌨️ 快捷键说明

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