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

📄 cypress_m8.c

📁 usb driver for 2.6.17
💻 C
📖 第 1 页 / 共 4 页
字号:
	spin_lock_irqsave(&priv->lock, flags);	++priv->cmd_count;	spin_unlock_irqrestore(&priv->lock, flags);	return retval;} /* cypress_serial_control *//* given a baud mask, it will return integer baud on success */static int mask_to_rate (unsigned mask){	int rate;	switch (mask) {		case B0: rate = 0; break;		case B300: rate = 300; break;		case B600: rate = 600; break;		case B1200: rate = 1200; break;		case B2400: rate = 2400; break;		case B4800: rate = 4800; break;		case B9600: rate = 9600; break;		case B19200: rate = 19200; break;		case B38400: rate = 38400; break;		case B57600: rate = 57600; break;		case B115200: rate = 115200; break;		default: rate = -1;	}	return rate;}static unsigned rate_to_mask (int rate){	unsigned mask;	switch (rate) {		case 0: mask = B0; break;		case 300: mask = B300; break;		case 600: mask = B600; break;		case 1200: mask = B1200; break;		case 2400: mask = B2400; break;		case 4800: mask = B4800; break;		case 9600: mask = B9600; break;		case 19200: mask = B19200; break;		case 38400: mask = B38400; break;		case 57600: mask = B57600; break;		case 115200: mask = B115200; break;		default: mask = 0x40;	}	return mask;}/***************************************************************************** * Cypress serial driver functions *****************************************************************************/static int generic_startup (struct usb_serial *serial){	struct cypress_private *priv;	dbg("%s - port %d", __FUNCTION__, serial->port[0]->number);	priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL);	if (!priv)		return -ENOMEM;	spin_lock_init(&priv->lock);	priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE);	if (priv->buf == NULL) {		kfree(priv);		return -ENOMEM;	}	init_waitqueue_head(&priv->delta_msr_wait);		usb_reset_configuration (serial->dev);		interval = 1;	priv->cmd_ctrl = 0;	priv->line_control = 0;	priv->termios_initialized = 0;	priv->rx_flags = 0;	priv->cbr_mask = B300;	usb_set_serial_port_data(serial->port[0], priv);		return 0;}static int cypress_earthmate_startup (struct usb_serial *serial){	struct cypress_private *priv;	dbg("%s", __FUNCTION__);	if (generic_startup(serial)) {		dbg("%s - Failed setting up port %d", __FUNCTION__,				serial->port[0]->number);		return 1;	}	priv = usb_get_serial_port_data(serial->port[0]);	priv->chiptype = CT_EARTHMATE;	return 0;} /* cypress_earthmate_startup */static int cypress_hidcom_startup (struct usb_serial *serial){	struct cypress_private *priv;	dbg("%s", __FUNCTION__);	if (generic_startup(serial)) {		dbg("%s - Failed setting up port %d", __FUNCTION__,				serial->port[0]->number);		return 1;	}	priv = usb_get_serial_port_data(serial->port[0]);	priv->chiptype = CT_CYPHIDCOM;		return 0;} /* cypress_hidcom_startup */static int cypress_ca42v2_startup (struct usb_serial *serial){	struct cypress_private *priv;	dbg("%s", __FUNCTION__);	if (generic_startup(serial)) {		dbg("%s - Failed setting up port %d", __FUNCTION__,				serial->port[0]->number);		return 1;	}	priv = usb_get_serial_port_data(serial->port[0]);	priv->chiptype = CT_CA42V2;	return 0;} /* cypress_ca42v2_startup */static void cypress_shutdown (struct usb_serial *serial){	struct cypress_private *priv;	dbg ("%s - port %d", __FUNCTION__, serial->port[0]->number);	/* all open ports are closed at this point */	priv = usb_get_serial_port_data(serial->port[0]);	if (priv) {		cypress_buf_free(priv->buf);		kfree(priv);		usb_set_serial_port_data(serial->port[0], NULL);	}}static int cypress_open (struct usb_serial_port *port, struct file *filp){	struct cypress_private *priv = usb_get_serial_port_data(port);	struct usb_serial *serial = port->serial;	unsigned long flags;	int result = 0;	dbg("%s - port %d", __FUNCTION__, port->number);	/* clear halts before open */	usb_clear_halt(serial->dev, 0x81);	usb_clear_halt(serial->dev, 0x02);	spin_lock_irqsave(&priv->lock, flags);	/* reset read/write statistics */	priv->bytes_in = 0;	priv->bytes_out = 0;	priv->cmd_count = 0;	priv->rx_flags = 0;	spin_unlock_irqrestore(&priv->lock, flags);	/* setting to zero could cause data loss */	port->tty->low_latency = 1;	/* raise both lines and set termios */	spin_lock_irqsave(&priv->lock, flags);	priv->line_control = CONTROL_DTR | CONTROL_RTS;	priv->cmd_ctrl = 1;	spin_unlock_irqrestore(&priv->lock, flags);	result = cypress_write(port, NULL, 0);	if (result) {		dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __FUNCTION__, result);		return result;	} else		dbg("%s - success setting the control lines", __FUNCTION__);		cypress_set_termios(port, &priv->tmp_termios);	/* setup the port and start reading from the device */	if(!port->interrupt_in_urb){		err("%s - interrupt_in_urb is empty!", __FUNCTION__);		return(-1);	}	usb_fill_int_urb(port->interrupt_in_urb, serial->dev,		usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),		port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,		cypress_read_int_callback, port, interval);	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);	if (result){		dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);	}	return result;} /* cypress_open */static void cypress_close(struct usb_serial_port *port, struct file * filp){	struct cypress_private *priv = usb_get_serial_port_data(port);	unsigned int c_cflag;	unsigned long flags;	int bps;	long timeout;	wait_queue_t wait;	dbg("%s - port %d", __FUNCTION__, port->number);	/* wait for data to drain from buffer */	spin_lock_irqsave(&priv->lock, flags);	timeout = CYPRESS_CLOSING_WAIT;	init_waitqueue_entry(&wait, current);	add_wait_queue(&port->tty->write_wait, &wait);	for (;;) {		set_current_state(TASK_INTERRUPTIBLE);		if (cypress_buf_data_avail(priv->buf) == 0		|| timeout == 0 || signal_pending(current)		|| !usb_get_intfdata(port->serial->interface))			break;		spin_unlock_irqrestore(&priv->lock, flags);		timeout = schedule_timeout(timeout);		spin_lock_irqsave(&priv->lock, flags);	}	set_current_state(TASK_RUNNING);	remove_wait_queue(&port->tty->write_wait, &wait);	/* clear out any remaining data in the buffer */	cypress_buf_clear(priv->buf);	spin_unlock_irqrestore(&priv->lock, flags);		/* wait for characters to drain from device */	bps = tty_get_baud_rate(port->tty);	if (bps > 1200)		timeout = max((HZ*2560)/bps,HZ/10);	else		timeout = 2*HZ;	schedule_timeout_interruptible(timeout);	dbg("%s - stopping urbs", __FUNCTION__);	usb_kill_urb (port->interrupt_in_urb);	usb_kill_urb (port->interrupt_out_urb);	if (port->tty) {		c_cflag = port->tty->termios->c_cflag;		if (c_cflag & HUPCL) {			/* drop dtr and rts */			priv = usb_get_serial_port_data(port);			spin_lock_irqsave(&priv->lock, flags);			priv->line_control = 0;			priv->cmd_ctrl = 1;			spin_unlock_irqrestore(&priv->lock, flags);			cypress_write(port, NULL, 0);		}	}	if (stats)		dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",		          priv->bytes_in, priv->bytes_out, priv->cmd_count);} /* cypress_close */static int cypress_write(struct usb_serial_port *port, const unsigned char *buf, int count){	struct cypress_private *priv = usb_get_serial_port_data(port);	unsigned long flags;		dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count);	/* line control commands, which need to be executed immediately,	   are not put into the buffer for obvious reasons.	 */	if (priv->cmd_ctrl) {		count = 0;		goto finish;	}		if (!count)		return count;		spin_lock_irqsave(&priv->lock, flags);	count = cypress_buf_put(priv->buf, buf, count);	spin_unlock_irqrestore(&priv->lock, flags);finish:	cypress_send(port);	return count;} /* cypress_write */static void cypress_send(struct usb_serial_port *port){	int count = 0, result, offset, actual_size;	struct cypress_private *priv = usb_get_serial_port_data(port);	unsigned long flags;		dbg("%s - port %d", __FUNCTION__, port->number);	dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size);		spin_lock_irqsave(&priv->lock, flags);	if (priv->write_urb_in_use) {		dbg("%s - can't write, urb in use", __FUNCTION__);		spin_unlock_irqrestore(&priv->lock, flags);		return;	}	spin_unlock_irqrestore(&priv->lock, flags);	/* clear buffer */	memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size);	spin_lock_irqsave(&priv->lock, flags);	switch (port->interrupt_out_size) {		case 32:			/* this is for the CY7C64013... */			offset = 2;			port->interrupt_out_buffer[0] = priv->line_control;			break;		case 8:			/* this is for the CY7C63743... */			offset = 1;			port->interrupt_out_buffer[0] = priv->line_control;			break;		default:			dbg("%s - wrong packet size", __FUNCTION__);			spin_unlock_irqrestore(&priv->lock, flags);			return;	}	if (priv->line_control & CONTROL_RESET)		priv->line_control &= ~CONTROL_RESET;	if (priv->cmd_ctrl) {		priv->cmd_count++;		dbg("%s - line control command being issued", __FUNCTION__);		spin_unlock_irqrestore(&priv->lock, flags);		goto send;	} else		spin_unlock_irqrestore(&priv->lock, flags);	count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset],				port->interrupt_out_size-offset);	if (count == 0) {		return;	}	switch (port->interrupt_out_size) {		case 32:			port->interrupt_out_buffer[1] = count;			break;		case 8:			port->interrupt_out_buffer[0] |= count;	}	dbg("%s - count is %d", __FUNCTION__, count);send:	spin_lock_irqsave(&priv->lock, flags);	priv->write_urb_in_use = 1;	spin_unlock_irqrestore(&priv->lock, flags);	if (priv->cmd_ctrl)		actual_size = 1;	else		actual_size = count + (port->interrupt_out_size == 32 ? 2 : 1);		usb_serial_debug_data(debug, &port->dev, __FUNCTION__, port->interrupt_out_size,			      port->interrupt_out_urb->transfer_buffer);	port->interrupt_out_urb->transfer_buffer_length = actual_size;	port->interrupt_out_urb->dev = port->serial->dev;	port->interrupt_out_urb->interval = interval;	result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);	if (result) {		dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,			result);		priv->write_urb_in_use = 0;	}	spin_lock_irqsave(&priv->lock, flags);	if (priv->cmd_ctrl) {		priv->cmd_ctrl = 0;	}	priv->bytes_out += count; /* do not count the line control and size bytes */	spin_unlock_irqrestore(&priv->lock, flags);	schedule_work(&port->work);} /* cypress_send */

⌨️ 快捷键说明

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