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

📄 mct_u232.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
{	struct usb_serial *serial = port->serial;	struct mct_u232_private *priv = usb_get_serial_port_data(port);	int retval = 0;	unsigned int control_state;	unsigned long flags;	unsigned char last_lcr;	unsigned char last_msr;	dbg("%s port %d", __FUNCTION__, port->number);	/* Compensate for a hardware bug: although the Sitecom U232-P25	 * device reports a maximum output packet size of 32 bytes,	 * it seems to be able to accept only 16 bytes (and that's what	 * SniffUSB says too...)	 */	if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID)		port->bulk_out_size = 16;	/* Do a defined restart: the normal serial device seems to 	 * always turn on DTR and RTS here, so do the same. I'm not	 * sure if this is really necessary. But it should not harm	 * either.	 */	spin_lock_irqsave(&priv->lock, flags);	if (port->tty->termios->c_cflag & CBAUD)		priv->control_state = TIOCM_DTR | TIOCM_RTS;	else		priv->control_state = 0;		priv->last_lcr = (MCT_U232_DATA_BITS_8 | 			  MCT_U232_PARITY_NONE |			  MCT_U232_STOP_BITS_1);	control_state = priv->control_state;	last_lcr = priv->last_lcr;	spin_unlock_irqrestore(&priv->lock, flags);	mct_u232_set_modem_ctrl(serial, control_state);	mct_u232_set_line_ctrl(serial, last_lcr);	/* Read modem status and update control state */	mct_u232_get_modem_stat(serial, &last_msr);	spin_lock_irqsave(&priv->lock, flags);	priv->last_msr = last_msr;	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);	spin_unlock_irqrestore(&priv->lock, flags);	port->read_urb->dev = port->serial->dev;	retval = usb_submit_urb(port->read_urb, GFP_KERNEL);	if (retval) {		err("usb_submit_urb(read bulk) failed pipe 0x%x err %d",		    port->read_urb->pipe, retval);		goto exit;	}	port->interrupt_in_urb->dev = port->serial->dev;	retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);	if (retval)		err(" usb_submit_urb(read int) failed pipe 0x%x err %d",		    port->interrupt_in_urb->pipe, retval);exit:	return 0;} /* mct_u232_open */static void mct_u232_close (struct usb_serial_port *port, struct file *filp){	dbg("%s port %d", __FUNCTION__, port->number);	if (port->serial->dev) {		/* shutdown our urbs */		usb_kill_urb(port->write_urb);		usb_kill_urb(port->read_urb);		usb_kill_urb(port->interrupt_in_urb);	}} /* mct_u232_close */static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct mct_u232_private *priv = usb_get_serial_port_data(port);	struct usb_serial *serial = port->serial;	struct tty_struct *tty;	unsigned char *data = urb->transfer_buffer;	int status;	unsigned long flags;	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);		return;	default:		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);		goto exit;	}	if (!serial) {		dbg("%s - bad serial pointer, exiting", __FUNCTION__);		return;	}        dbg("%s - port %d", __FUNCTION__, port->number);	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);	/*	 * Work-a-round: handle the 'usual' bulk-in pipe here	 */	if (urb->transfer_buffer_length > 2) {		int i;		tty = port->tty;		if (urb->actual_length) {			for (i = 0; i < urb->actual_length ; ++i) {				tty_insert_flip_char(tty, data[i], 0);			}			tty_flip_buffer_push(tty);		}		goto exit;	}		/*	 * The interrupt-in pipe signals exceptional conditions (modem line	 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.	 */	spin_lock_irqsave(&priv->lock, flags);	priv->last_msr = data[MCT_U232_MSR_INDEX];		/* Record Control Line states */	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);#if 0	/* Not yet handled. See belin_sa.c for further information */	/* Now to report any errors */	priv->last_lsr = data[MCT_U232_LSR_INDEX];	/*	 * fill in the flip buffer here, but I do not know the relation	 * to the current/next receive buffer or characters.  I need	 * to look in to this before committing any code.	 */	if (priv->last_lsr & MCT_U232_LSR_ERR) {		tty = port->tty;		/* Overrun Error */		if (priv->last_lsr & MCT_U232_LSR_OE) {		}		/* Parity Error */		if (priv->last_lsr & MCT_U232_LSR_PE) {		}		/* Framing Error */		if (priv->last_lsr & MCT_U232_LSR_FE) {		}		/* Break Indicator */		if (priv->last_lsr & MCT_U232_LSR_BI) {		}	}#endif	spin_unlock_irqrestore(&priv->lock, flags);exit:	status = usb_submit_urb (urb, GFP_ATOMIC);	if (status)		err ("%s - usb_submit_urb failed with result %d",		     __FUNCTION__, status);} /* mct_u232_read_int_callback */static void mct_u232_set_termios (struct usb_serial_port *port,				  struct termios *old_termios){	struct usb_serial *serial = port->serial;	struct mct_u232_private *priv = usb_get_serial_port_data(port);	unsigned int iflag = port->tty->termios->c_iflag;	unsigned int cflag = port->tty->termios->c_cflag;	unsigned int old_cflag = old_termios->c_cflag;	unsigned long flags;	unsigned int control_state, new_state;	unsigned char last_lcr;	/* get a local copy of the current port settings */	spin_lock_irqsave(&priv->lock, flags);	control_state = priv->control_state;	spin_unlock_irqrestore(&priv->lock, flags);	last_lcr = 0;	/*	 * Update baud rate.	 * Do not attempt to cache old rates and skip settings,	 * disconnects screw such tricks up completely.	 * Premature optimization is the root of all evil.	 */        /* reassert DTR and (maybe) RTS on transition from B0 */	if ((old_cflag & CBAUD) == B0) {		dbg("%s: baud was B0", __FUNCTION__);		control_state |= TIOCM_DTR;		/* don't set RTS if using hardware flow control */		if (!(old_cflag & CRTSCTS)) {			control_state |= TIOCM_RTS;		}		mct_u232_set_modem_ctrl(serial, control_state);	}	mct_u232_set_baud_rate(serial, cflag & CBAUD);	if ((cflag & CBAUD) == B0 ) {		dbg("%s: baud is B0", __FUNCTION__);		/* Drop RTS and DTR */		control_state &= ~(TIOCM_DTR | TIOCM_RTS);       		mct_u232_set_modem_ctrl(serial, control_state);	}	/*	 * Update line control register (LCR)	 */	/* set the parity */	if (cflag & PARENB)		last_lcr |= (cflag & PARODD) ?			MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;	else		last_lcr |= MCT_U232_PARITY_NONE;	/* set the number of data bits */	switch (cflag & CSIZE) {	case CS5:		last_lcr |= MCT_U232_DATA_BITS_5; break;	case CS6:		last_lcr |= MCT_U232_DATA_BITS_6; break;	case CS7:		last_lcr |= MCT_U232_DATA_BITS_7; break;	case CS8:		last_lcr |= MCT_U232_DATA_BITS_8; break;	default:		err("CSIZE was not CS5-CS8, using default of 8");		last_lcr |= MCT_U232_DATA_BITS_8;		break;	}	/* set the number of stop bits */	last_lcr |= (cflag & CSTOPB) ?		MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;	mct_u232_set_line_ctrl(serial, last_lcr);	/*	 * Set flow control: well, I do not really now how to handle DTR/RTS.	 * Just do what we have seen with SniffUSB on Win98.	 */	/* Drop DTR/RTS if no flow control otherwise assert */	new_state = control_state;	if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))		new_state |= TIOCM_DTR | TIOCM_RTS;	else		new_state &= ~(TIOCM_DTR | TIOCM_RTS);	if (new_state != control_state) {		mct_u232_set_modem_ctrl(serial, new_state);		control_state = new_state;	}	/* save off the modified port settings */	spin_lock_irqsave(&priv->lock, flags);	priv->control_state = control_state;	priv->last_lcr = last_lcr;	spin_unlock_irqrestore(&priv->lock, flags);} /* mct_u232_set_termios */static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state ){	struct usb_serial *serial = port->serial;	struct mct_u232_private *priv = usb_get_serial_port_data(port);	unsigned char lcr;	unsigned long flags;	dbg("%sstate=%d", __FUNCTION__, break_state);	spin_lock_irqsave(&priv->lock, flags);	lcr = priv->last_lcr;	spin_unlock_irqrestore(&priv->lock, flags);	if (break_state)		lcr |= MCT_U232_SET_BREAK;	mct_u232_set_line_ctrl(serial, lcr);} /* mct_u232_break_ctl */static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file){	struct mct_u232_private *priv = usb_get_serial_port_data(port);	unsigned int control_state;	unsigned long flags;		dbg("%s", __FUNCTION__);	spin_lock_irqsave(&priv->lock, flags);	control_state = priv->control_state;	spin_unlock_irqrestore(&priv->lock, flags);	return control_state;}static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file,			      unsigned int set, unsigned int clear){	struct usb_serial *serial = port->serial;	struct mct_u232_private *priv = usb_get_serial_port_data(port);	unsigned int control_state;	unsigned long flags;		dbg("%s", __FUNCTION__);	spin_lock_irqsave(&priv->lock, flags);	control_state = priv->control_state;	if (set & TIOCM_RTS)		control_state |= TIOCM_RTS;	if (set & TIOCM_DTR)		control_state |= TIOCM_DTR;	if (clear & TIOCM_RTS)		control_state &= ~TIOCM_RTS;	if (clear & TIOCM_DTR)		control_state &= ~TIOCM_DTR;	priv->control_state = control_state;	spin_unlock_irqrestore(&priv->lock, flags);	return mct_u232_set_modem_ctrl(serial, control_state);}static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,			   unsigned int cmd, unsigned long arg){	dbg("%scmd=0x%x", __FUNCTION__, cmd);	/* Based on code from acm.c and others */	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;	default:		dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd);		return(-ENOIOCTLCMD);		break;	}	return 0;} /* mct_u232_ioctl */static int __init mct_u232_init (void){	int retval;	retval = usb_serial_register(&mct_u232_device);	if (retval)		goto failed_usb_serial_register;	retval = usb_register(&mct_u232_driver);	if (retval)		goto failed_usb_register;	info(DRIVER_DESC " " DRIVER_VERSION);	return 0;failed_usb_register:	usb_serial_deregister(&mct_u232_device);failed_usb_serial_register:	return retval;}static void __exit mct_u232_exit (void){	usb_deregister (&mct_u232_driver);	usb_serial_deregister (&mct_u232_device);}module_init (mct_u232_init);module_exit(mct_u232_exit);MODULE_AUTHOR( DRIVER_AUTHOR );MODULE_DESCRIPTION( DRIVER_DESC );MODULE_LICENSE("GPL");module_param(debug, bool, S_IRUGO | S_IWUSR);MODULE_PARM_DESC(debug, "Debug enabled or not");

⌨️ 快捷键说明

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