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

📄 digi_acceleport.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
				modem_signals |= TIOCM_RTS;			digi_set_modem_signals(port, modem_signals, 1);		}		switch (baud) {			/* drop DTR and RTS on transition to B0 */			case 0: digi_set_modem_signals(port, 0, 1); break;			case 50: arg = DIGI_BAUD_50; break;			case 75: arg = DIGI_BAUD_75; break;			case 110: arg = DIGI_BAUD_110; break;			case 150: arg = DIGI_BAUD_150; break;			case 200: arg = DIGI_BAUD_200; break;			case 300: arg = DIGI_BAUD_300; break;			case 600: arg = DIGI_BAUD_600; break;			case 1200: arg = DIGI_BAUD_1200; break;			case 1800: arg = DIGI_BAUD_1800; break;			case 2400: arg = DIGI_BAUD_2400; break;			case 4800: arg = DIGI_BAUD_4800; break;			case 9600: arg = DIGI_BAUD_9600; break;			case 19200: arg = DIGI_BAUD_19200; break;			case 38400: arg = DIGI_BAUD_38400; break;			case 57600: arg = DIGI_BAUD_57600; break;			case 115200: arg = DIGI_BAUD_115200; break;			case 230400: arg = DIGI_BAUD_230400; break;			case 460800: arg = DIGI_BAUD_460800; break;			default:				arg = DIGI_BAUD_9600;				baud = 9600;				break;		}		if (arg != -1) {			buf[i++] = DIGI_CMD_SET_BAUD_RATE;			buf[i++] = priv->dp_port_num;			buf[i++] = arg;			buf[i++] = 0;		}	}	/* set parity */	tty->termios->c_cflag &= ~CMSPAR;	if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) {		if (cflag&PARENB) {			if (cflag&PARODD)				arg = DIGI_PARITY_ODD;			else				arg = DIGI_PARITY_EVEN;		} else {			arg = DIGI_PARITY_NONE;		}		buf[i++] = DIGI_CMD_SET_PARITY;		buf[i++] = priv->dp_port_num;		buf[i++] = arg;		buf[i++] = 0;	}	/* set word size */	if ((cflag&CSIZE) != (old_cflag&CSIZE)) {		arg = -1;		switch (cflag&CSIZE) {		case CS5: arg = DIGI_WORD_SIZE_5; break;		case CS6: arg = DIGI_WORD_SIZE_6; break;		case CS7: arg = DIGI_WORD_SIZE_7; break;		case CS8: arg = DIGI_WORD_SIZE_8; break;		default:			dbg("digi_set_termios: can't handle word size %d",				(cflag&CSIZE));			break;		}		if (arg != -1) {			buf[i++] = DIGI_CMD_SET_WORD_SIZE;			buf[i++] = priv->dp_port_num;			buf[i++] = arg;			buf[i++] = 0;		}	}	/* set stop bits */	if ((cflag&CSTOPB) != (old_cflag&CSTOPB)) {		if ((cflag&CSTOPB))			arg = DIGI_STOP_BITS_2;		else			arg = DIGI_STOP_BITS_1;		buf[i++] = DIGI_CMD_SET_STOP_BITS;		buf[i++] = priv->dp_port_num;		buf[i++] = arg;		buf[i++] = 0;	}	/* set input flow control */	if ((iflag&IXOFF) != (old_iflag&IXOFF)	    || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) {		arg = 0;		if (iflag&IXOFF)			arg |= DIGI_INPUT_FLOW_CONTROL_XON_XOFF;		else			arg &= ~DIGI_INPUT_FLOW_CONTROL_XON_XOFF;		if (cflag&CRTSCTS) {			arg |= DIGI_INPUT_FLOW_CONTROL_RTS;			/* On USB-4 it is necessary to assert RTS prior */			/* to selecting RTS input flow control.  */			buf[i++] = DIGI_CMD_SET_RTS_SIGNAL;			buf[i++] = priv->dp_port_num;			buf[i++] = DIGI_RTS_ACTIVE;			buf[i++] = 0;		} else {			arg &= ~DIGI_INPUT_FLOW_CONTROL_RTS;		}		buf[i++] = DIGI_CMD_SET_INPUT_FLOW_CONTROL;		buf[i++] = priv->dp_port_num;		buf[i++] = arg;		buf[i++] = 0;	}	/* set output flow control */	if ((iflag & IXON) != (old_iflag & IXON)	    || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {		arg = 0;		if (iflag & IXON)			arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;		else			arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;		if (cflag & CRTSCTS) {			arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS;		} else {			arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS;			tty->hw_stopped = 0;		}		buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL;		buf[i++] = priv->dp_port_num;		buf[i++] = arg;		buf[i++] = 0;	}	/* set receive enable/disable */	if ((cflag & CREAD) != (old_cflag & CREAD)) {		if (cflag & CREAD)			arg = DIGI_ENABLE;		else			arg = DIGI_DISABLE;		buf[i++] = DIGI_CMD_RECEIVE_ENABLE;		buf[i++] = priv->dp_port_num;		buf[i++] = arg;		buf[i++] = 0;	}	if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0)		dbg("digi_set_termios: write oob failed, ret=%d", ret);	tty_encode_baud_rate(tty, baud, baud);}static void digi_break_ctl(struct usb_serial_port *port, int break_state){	unsigned char buf[4];	buf[0] = DIGI_CMD_BREAK_CONTROL;	buf[1] = 2;				/* length */	buf[2] = break_state ? 1 : 0;	buf[3] = 0;				/* pad */	digi_write_inb_command(port, buf, 4, 0);}static int digi_tiocmget(struct usb_serial_port *port, struct file *file){	struct digi_port *priv = usb_get_serial_port_data(port);	unsigned int val;	unsigned long flags;	dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num);	spin_lock_irqsave(&priv->dp_port_lock, flags);	val = priv->dp_modem_signals;	spin_unlock_irqrestore(&priv->dp_port_lock, flags);	return val;}static int digi_tiocmset(struct usb_serial_port *port, struct file *file,	unsigned int set, unsigned int clear){	struct digi_port *priv = usb_get_serial_port_data(port);	unsigned int val;	unsigned long flags;	dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num);	spin_lock_irqsave(&priv->dp_port_lock, flags);	val = (priv->dp_modem_signals & ~clear) | set;	spin_unlock_irqrestore(&priv->dp_port_lock, flags);	return digi_set_modem_signals(port, val, 1);}static int digi_ioctl(struct usb_serial_port *port, struct file *file,	unsigned int cmd, unsigned long arg){	struct digi_port *priv = usb_get_serial_port_data(port);	dbg("digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd);	switch (cmd) {	case TIOCMIWAIT:		/* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/		/* TODO */		return 0;	case TIOCGICOUNT:		/* return count of modemline transitions */		/* TODO */		return 0;	}	return -ENOIOCTLCMD;}static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count){	int ret,data_len,new_len;	struct digi_port *priv = usb_get_serial_port_data(port);	unsigned char *data = port->write_urb->transfer_buffer;	unsigned long flags = 0;	dbg("digi_write: TOP: port=%d, count=%d, in_interrupt=%ld",		priv->dp_port_num, count, in_interrupt());	/* copy user data (which can sleep) before getting spin lock */	count = min(count, port->bulk_out_size-2);	count = min(64, count);	/* be sure only one write proceeds at a time */	/* there are races on the port private buffer */	/* and races to check write_urb->status */	spin_lock_irqsave(&priv->dp_port_lock, flags);	/* wait for urb status clear to submit another urb */	if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) {		/* buffer data if count is 1 (probably put_char) if possible */		if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) {			priv->dp_out_buf[priv->dp_out_buf_len++] = *buf;			new_len = 1;		} else {			new_len = 0;		}		spin_unlock_irqrestore(&priv->dp_port_lock, flags);		return new_len;	}	/* allow space for any buffered data and for new data, up to */	/* transfer buffer size - 2 (for command and length bytes) */	new_len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len);	data_len = new_len + priv->dp_out_buf_len;	if (data_len == 0) {		spin_unlock_irqrestore(&priv->dp_port_lock, flags);		return 0;	}	port->write_urb->transfer_buffer_length = data_len+2;	port->write_urb->dev = port->serial->dev;	*data++ = DIGI_CMD_SEND_DATA;	*data++ = data_len;	/* copy in buffered data first */	memcpy(data, priv->dp_out_buf, priv->dp_out_buf_len);	data += priv->dp_out_buf_len;	/* copy in new data */	memcpy(data, buf, new_len);	if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {		priv->dp_write_urb_in_use = 1;		ret = new_len;		priv->dp_out_buf_len = 0;	}	/* return length of new data written, or error */	spin_unlock_irqrestore(&priv->dp_port_lock, flags);	if (ret < 0)		err("%s: usb_submit_urb failed, ret=%d, port=%d",			__FUNCTION__, ret, priv->dp_port_num);	dbg("digi_write: returning %d", ret);	return ret;} static void digi_write_bulk_callback(struct urb *urb){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct usb_serial *serial;	struct digi_port *priv;	struct digi_serial *serial_priv;	int ret = 0;	int status = urb->status;	dbg("digi_write_bulk_callback: TOP, urb->status=%d", status);	/* port and serial sanity check */	if (port == NULL || (priv=usb_get_serial_port_data(port)) == NULL) {		err("%s: port or port->private is NULL, status=%d",		    __FUNCTION__, status);		return;	}	serial = port->serial;	if (serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL) {		err("%s: serial or serial->private is NULL, status=%d",		    __FUNCTION__, status);		return;	}	/* handle oob callback */	if (priv->dp_port_num == serial_priv->ds_oob_port_num) {		dbg("digi_write_bulk_callback: oob callback");		spin_lock(&priv->dp_port_lock);		priv->dp_write_urb_in_use = 0;		wake_up_interruptible(&port->write_wait);		spin_unlock(&priv->dp_port_lock);		return;	}	/* try to send any buffered data on this port, if it is open */	spin_lock(&priv->dp_port_lock);	priv->dp_write_urb_in_use = 0;	if (port->open_count && port->write_urb->status != -EINPROGRESS	    && priv->dp_out_buf_len > 0) {		*((unsigned char *)(port->write_urb->transfer_buffer))			= (unsigned char)DIGI_CMD_SEND_DATA;		*((unsigned char *)(port->write_urb->transfer_buffer)+1)			= (unsigned char)priv->dp_out_buf_len;		port->write_urb->transfer_buffer_length = priv->dp_out_buf_len+2;		port->write_urb->dev = serial->dev;		memcpy(port->write_urb->transfer_buffer+2, priv->dp_out_buf,			priv->dp_out_buf_len);		if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {			priv->dp_write_urb_in_use = 1;			priv->dp_out_buf_len = 0;		}	}	/* wake up processes sleeping on writes immediately */	digi_wakeup_write(port);	/* also queue up a wakeup at scheduler time, in case we */	/* lost the race in write_chan(). */	schedule_work(&priv->dp_wakeup_work);	spin_unlock(&priv->dp_port_lock);	if (ret)		err("%s: usb_submit_urb failed, ret=%d, port=%d",			__FUNCTION__, ret, priv->dp_port_num);}static int digi_write_room(struct usb_serial_port *port){	int room;	struct digi_port *priv = usb_get_serial_port_data(port);	unsigned long flags = 0;	spin_lock_irqsave(&priv->dp_port_lock, flags);	if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use)		room = 0;	else		room = port->bulk_out_size - 2 - priv->dp_out_buf_len;	spin_unlock_irqrestore(&priv->dp_port_lock, flags);	dbg("digi_write_room: port=%d, room=%d", priv->dp_port_num, room);	return room;}static int digi_chars_in_buffer(struct usb_serial_port *port){	struct digi_port *priv = usb_get_serial_port_data(port);	if (port->write_urb->status == -EINPROGRESS	    || priv->dp_write_urb_in_use) {		dbg("digi_chars_in_buffer: port=%d, chars=%d",			priv->dp_port_num, port->bulk_out_size - 2);		/* return(port->bulk_out_size - 2); */		return 256;	} else {		dbg("digi_chars_in_buffer: port=%d, chars=%d",			priv->dp_port_num, priv->dp_out_buf_len);		return priv->dp_out_buf_len;	}}static int digi_open(struct usb_serial_port *port, struct file *filp){	int ret;	unsigned char buf[32];	struct digi_port *priv = usb_get_serial_port_data(port);	struct ktermios not_termios;	unsigned long flags = 0;	dbg("digi_open: TOP: port=%d, open_count=%d",		priv->dp_port_num, port->open_count);	/* be sure the device is started up */	if (digi_startup_device(port->serial) != 0)		return -ENXIO;	spin_lock_irqsave(&priv->dp_port_lock, flags);	/* don't wait on a close in progress for non-blocking opens */	if (priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) {		spin_unlock_irqrestore(&priv->dp_port_lock, flags);		return -EAGAIN;	}	/* wait for a close in progress to finish */	while(priv->dp_in_close) {		cond_wait_interruptible_timeout_irqrestore(			&priv->dp_close_wait, DIGI_RETRY_TIMEOUT,			&priv->dp_port_lock, flags);		if (signal_pending(current))			return -EINTR;		spin_lock_irqsave(&priv->dp_port_lock, flags);	}	spin_unlock_irqrestore(&priv->dp_port_lock, flags); 	/* read modem signals automatically whenever they change */	buf[0] = DIGI_CMD_READ_INPUT_SIGNALS;	buf[1] = priv->dp_port_num;	buf[2] = DIGI_ENABLE;	buf[3] = 0;	/* flush fifos */	buf[4] = DIGI_CMD_IFLUSH_FIFO;	buf[5] = priv->dp_port_num;	buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;	buf[7] = 0;	if ((ret = digi_write_oob_command(port, buf, 8, 1)) != 0)		dbg("digi_open: write oob failed, ret=%d", ret);	/* set termios settings */	not_termios.c_cflag = ~port->tty->termios->c_cflag;	not_termios.c_iflag = ~port->tty->termios->c_iflag;	digi_set_termios(port, &not_termios);	/* set DTR and RTS */	digi_set_modem_signals(port, TIOCM_DTR|TIOCM_RTS, 1);	return 0;}static void digi_close(struct usb_serial_port *port, struct file *filp){	DEFINE_WAIT(wait);	int ret;	unsigned char buf[32];	struct tty_struct *tty = port->tty;	struct digi_port *priv = usb_get_serial_port_data(port);

⌨️ 快捷键说明

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