diff options
Diffstat (limited to 'drivers/usb/serial/mct_u232.c')
| -rw-r--r-- | drivers/usb/serial/mct_u232.c | 344 | 
1 files changed, 116 insertions, 228 deletions
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2849f8c3201..fd707d6a10e 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -19,55 +19,10 @@   *   DTR/RTS signal handling may be incomplete or incorrect. I have mainly   *   implemented what I have seen with SniffUSB or found in belkin_sa.c.   *   For further TODOs check also belkin_sa.c. - * - * TEST STATUS: - *   Basic tests have been performed with minicom/zmodem transfers and - *   modem dialing under Linux 2.4.0-test10 (for me it works fine). - * - * 04-Nov-2003 Bill Marr <marr at flex dot com> - *   - Mimic Windows driver by sending 2 USB 'device request' messages - *     following normal 'baud rate change' message.  This allows data to be - *     transmitted to RS-232 devices which don't assert the 'CTS' signal. - * - * 10-Nov-2001 Wolfgang Grandegger - *   - Fixed an endianess problem with the baudrate selection for PowerPC. - * - * 06-Dec-2001 Martin Hamilton <martinh@gnu.org> - *   - Added support for the Belkin F5U109 DB9 adaptor - * - * 30-May-2001 Greg Kroah-Hartman - *   - switched from using spinlock to a semaphore, which fixes lots of - *     problems. - * - * 04-May-2001 Stelian Pop - *   - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes - *     instead of the device reported 32 (using 32 bytes causes many data - *     loss, Windows driver uses 16 too). - * - * 02-May-2001 Stelian Pop - *   - Fixed the baud calculation for Sitecom U232-P25 model - * - * 08-Apr-2001 gb - *   - Identify version on module load. - * - * 06-Jan-2001 Cornel Ciocirlan - *   - Added support for Sitecom U232-P25 model (Product Id 0x0230) - *   - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200) - * - * 29-Nov-2000 Greg Kroah-Hartman - *   - Added device id table to fit with 2.4.0-test11 structure. - *   - took out DEAL_WITH_TWO_INT_IN_ENDPOINTS #define as it's not needed - *     (lots of things will change if/when the usb-serial core changes to - *     handle these issues. - * - * 27-Nov-2000 Wolfgang Grandegge - *   A version for kernel 2.4.0-test10 released to the Linux community - *   (via linux-usb-devel).   */  #include <linux/kernel.h>  #include <linux/errno.h> -#include <linux/init.h>  #include <linux/slab.h>  #include <linux/tty.h>  #include <linux/tty_driver.h> @@ -78,22 +33,17 @@  #include <asm/unaligned.h>  #include <linux/usb.h>  #include <linux/usb/serial.h> +#include <linux/serial.h>  #include "mct_u232.h" -/* - * Version Information - */ -#define DRIVER_VERSION "z2.1"		/* Linux in-kernel version */  #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"  #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" -static int debug; -  /*   * Function prototypes   */ -static int  mct_u232_startup(struct usb_serial *serial); -static void mct_u232_release(struct usb_serial *serial); +static int  mct_u232_port_probe(struct usb_serial_port *port); +static int  mct_u232_port_remove(struct usb_serial_port *remove);  static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);  static void mct_u232_close(struct usb_serial_port *port);  static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); @@ -101,8 +51,8 @@ static void mct_u232_read_int_callback(struct urb *urb);  static void mct_u232_set_termios(struct tty_struct *tty,  			struct usb_serial_port *port, struct ktermios *old);  static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); -static int  mct_u232_tiocmget(struct tty_struct *tty, struct file *file); -static int  mct_u232_tiocmset(struct tty_struct *tty, struct file *file, +static int  mct_u232_tiocmget(struct tty_struct *tty); +static int  mct_u232_tiocmset(struct tty_struct *tty,  			unsigned int set, unsigned int clear);  static void mct_u232_throttle(struct tty_struct *tty);  static void mct_u232_unthrottle(struct tty_struct *tty); @@ -111,23 +61,14 @@ static void mct_u232_unthrottle(struct tty_struct *tty);  /*   * All of the device info needed for the MCT USB-RS232 converter.   */ -static const struct usb_device_id id_table_combined[] = { +static const struct usb_device_id id_table[] = {  	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },  	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },  	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },  	{ USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },  	{ }		/* Terminating entry */  }; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver mct_u232_driver = { -	.name =		"mct_u232", -	.probe =	usb_serial_probe, -	.disconnect =	usb_serial_disconnect, -	.id_table =	id_table_combined, -	.no_dynamic_id = 	1, -}; +MODULE_DEVICE_TABLE(usb, id_table);  static struct usb_serial_driver mct_u232_device = {  	.driver = { @@ -135,8 +76,7 @@ static struct usb_serial_driver mct_u232_device = {  		.name =		"mct_u232",  	},  	.description =	     "MCT U232", -	.usb_driver = 	     &mct_u232_driver, -	.id_table =	     id_table_combined, +	.id_table =	     id_table,  	.num_ports =	     1,  	.open =		     mct_u232_open,  	.close =	     mct_u232_close, @@ -148,12 +88,18 @@ static struct usb_serial_driver mct_u232_device = {  	.break_ctl =	     mct_u232_break_ctl,  	.tiocmget =	     mct_u232_tiocmget,  	.tiocmset =	     mct_u232_tiocmset, -	.attach =	     mct_u232_startup, -	.release =	     mct_u232_release, +	.tiocmiwait =        usb_serial_generic_tiocmiwait, +	.port_probe =        mct_u232_port_probe, +	.port_remove =       mct_u232_port_remove, +	.get_icount =        usb_serial_generic_get_icount,  }; +static struct usb_serial_driver * const serial_drivers[] = { +	&mct_u232_device, NULL +};  struct mct_u232_private { +	struct urb *read_urb;  	spinlock_t lock;  	unsigned int	     control_state; /* Modem Line Setting (TIOCM) */  	unsigned char        last_lcr;      /* Line Control Register */ @@ -254,7 +200,7 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,  			value, rc);  	else  		tty_encode_baud_rate(tty, speed, speed); -	dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor); +	dev_dbg(&port->dev, "set_baud_rate: value: 0x%x, divisor: 0x%x\n", value, divisor);  	/* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which  	   always sends two extra USB 'device request' messages after the @@ -287,8 +233,8 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,  	if (port && C_CRTSCTS(tty))  	   cts_enable_byte = 1; -	dbg("set_baud_rate: send second control message, data = %02X", -							cts_enable_byte); +	dev_dbg(&port->dev, "set_baud_rate: send second control message, data = %02X\n", +		cts_enable_byte);  	buf[0] = cts_enable_byte;  	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),  			MCT_U232_SET_CTS_REQUEST, @@ -303,7 +249,8 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,  	return rc;  } /* mct_u232_set_baud_rate */ -static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr) +static int mct_u232_set_line_ctrl(struct usb_serial_port *port, +				  unsigned char lcr)  {  	int rc;  	unsigned char *buf; @@ -313,20 +260,19 @@ static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)  		return -ENOMEM;  	buf[0] = lcr; -	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), +	rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),  			MCT_U232_SET_LINE_CTRL_REQUEST,  			MCT_U232_SET_REQUEST_TYPE,  			0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,  			WDR_TIMEOUT);  	if (rc < 0) -		dev_err(&serial->dev->dev, -			"Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc); -	dbg("set_line_ctrl: 0x%x", lcr); +		dev_err(&port->dev, "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc); +	dev_dbg(&port->dev, "set_line_ctrl: 0x%x\n", lcr);  	kfree(buf);  	return rc;  } /* mct_u232_set_line_ctrl */ -static int mct_u232_set_modem_ctrl(struct usb_serial *serial, +static int mct_u232_set_modem_ctrl(struct usb_serial_port *port,  				   unsigned int control_state)  {  	int rc; @@ -344,22 +290,24 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial,  		mcr |= MCT_U232_MCR_RTS;  	buf[0] = mcr; -	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), +	rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),  			MCT_U232_SET_MODEM_CTRL_REQUEST,  			MCT_U232_SET_REQUEST_TYPE,  			0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,  			WDR_TIMEOUT); -	if (rc < 0) -		dev_err(&serial->dev->dev, -			"Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); -	dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); -  	kfree(buf); -	return rc; + +	dev_dbg(&port->dev, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state, mcr); + +	if (rc < 0) { +		dev_err(&port->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); +		return rc; +	} +	return 0;  } /* mct_u232_set_modem_ctrl */ -static int mct_u232_get_modem_stat(struct usb_serial *serial, -						unsigned char *msr) +static int mct_u232_get_modem_stat(struct usb_serial_port *port, +				   unsigned char *msr)  {  	int rc;  	unsigned char *buf; @@ -369,27 +317,40 @@ static int mct_u232_get_modem_stat(struct usb_serial *serial,  		*msr = 0;  		return -ENOMEM;  	} -	rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), +	rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),  			MCT_U232_GET_MODEM_STAT_REQUEST,  			MCT_U232_GET_REQUEST_TYPE,  			0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,  			WDR_TIMEOUT);  	if (rc < 0) { -		dev_err(&serial->dev->dev, -			"Get MODEM STATus failed (error = %d)\n", rc); +		dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);  		*msr = 0;  	} else {  		*msr = buf[0];  	} -	dbg("get_modem_stat: 0x%x", *msr); +	dev_dbg(&port->dev, "get_modem_stat: 0x%x\n", *msr);  	kfree(buf);  	return rc;  } /* mct_u232_get_modem_stat */ -static void mct_u232_msr_to_state(unsigned int *control_state, +static void mct_u232_msr_to_icount(struct async_icount *icount,  						unsigned char msr)  {  	/* Translate Control Line states */ +	if (msr & MCT_U232_MSR_DDSR) +		icount->dsr++; +	if (msr & MCT_U232_MSR_DCTS) +		icount->cts++; +	if (msr & MCT_U232_MSR_DRI) +		icount->rng++; +	if (msr & MCT_U232_MSR_DCD) +		icount->dcd++; +} /* mct_u232_msr_to_icount */ + +static void mct_u232_msr_to_state(struct usb_serial_port *port, +				  unsigned int *control_state, unsigned char msr) +{ +	/* Translate Control Line states */  	if (msr & MCT_U232_MSR_DSR)  		*control_state |=  TIOCM_DSR;  	else @@ -406,52 +367,41 @@ static void mct_u232_msr_to_state(unsigned int *control_state,  		*control_state |=  TIOCM_CD;  	else  		*control_state &= ~TIOCM_CD; -	dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state); +	dev_dbg(&port->dev, "msr_to_state: msr=0x%x ==> state=0x%x\n", msr, *control_state);  } /* mct_u232_msr_to_state */  /*   * Driver's tty interface functions   */ -static int mct_u232_startup(struct usb_serial *serial) +static int mct_u232_port_probe(struct usb_serial_port *port)  {  	struct mct_u232_private *priv; -	struct usb_serial_port *port, *rport; -	priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); +	priv = kzalloc(sizeof(*priv), GFP_KERNEL);  	if (!priv)  		return -ENOMEM; -	spin_lock_init(&priv->lock); -	usb_set_serial_port_data(serial->port[0], priv); -	init_waitqueue_head(&serial->port[0]->write_wait); +	/* Use second interrupt-in endpoint for reading. */ +	priv->read_urb = port->serial->port[1]->interrupt_in_urb; +	priv->read_urb->context = port; -	/* Puh, that's dirty */ -	port = serial->port[0]; -	rport = serial->port[1]; -	/* No unlinking, it wasn't submitted yet. */ -	usb_free_urb(port->read_urb); -	port->read_urb = rport->interrupt_in_urb; -	rport->interrupt_in_urb = NULL; -	port->read_urb->context = port; +	spin_lock_init(&priv->lock); -	return 0; -} /* mct_u232_startup */ +	usb_set_serial_port_data(port, priv); +	return 0; +} -static void mct_u232_release(struct usb_serial *serial) +static int mct_u232_port_remove(struct usb_serial_port *port)  {  	struct mct_u232_private *priv; -	int i; -	dbg("%s", __func__); +	priv = usb_get_serial_port_data(port); +	kfree(priv); -	for (i = 0; i < serial->num_ports; ++i) { -		/* My special items, the standard routines free my urbs */ -		priv = usb_get_serial_port_data(serial->port[i]); -		kfree(priv); -	} -} /* mct_u232_release */ +	return 0; +}  static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)  { @@ -463,8 +413,6 @@ static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)  	unsigned char last_lcr;  	unsigned char last_msr; -	dbg("%s port %d", __func__, 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 @@ -480,7 +428,7 @@ static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)  	 * either.  	 */  	spin_lock_irqsave(&priv->lock, flags); -	if (tty && (tty->termios->c_cflag & CBAUD)) +	if (tty && (tty->termios.c_cflag & CBAUD))  		priv->control_state = TIOCM_DTR | TIOCM_RTS;  	else  		priv->control_state = 0; @@ -491,29 +439,27 @@ static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)  	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); +	mct_u232_set_modem_ctrl(port, control_state); +	mct_u232_set_line_ctrl(port, last_lcr);  	/* Read modem status and update control state */ -	mct_u232_get_modem_stat(serial, &last_msr); +	mct_u232_get_modem_stat(port, &last_msr);  	spin_lock_irqsave(&priv->lock, flags);  	priv->last_msr = last_msr; -	mct_u232_msr_to_state(&priv->control_state, priv->last_msr); +	mct_u232_msr_to_state(port, &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); +	retval = usb_submit_urb(priv->read_urb, GFP_KERNEL);  	if (retval) {  		dev_err(&port->dev, -			"usb_submit_urb(read bulk) failed pipe 0x%x err %d\n", +			"usb_submit_urb(read) failed pipe 0x%x err %d\n",  			port->read_urb->pipe, retval);  		goto error;  	} -	port->interrupt_in_urb->dev = port->serial->dev;  	retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  	if (retval) { -		usb_kill_urb(port->read_urb); +		usb_kill_urb(priv->read_urb);  		dev_err(&port->dev,  			"usb_submit_urb(read int) failed pipe 0x%x err %d",  			port->interrupt_in_urb->pipe, retval); @@ -530,31 +476,25 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)  	unsigned int control_state;  	struct mct_u232_private *priv = usb_get_serial_port_data(port); -	mutex_lock(&port->serial->disc_mutex); -	if (!port->serial->disconnected) { -		/* drop DTR and RTS */ -		spin_lock_irq(&priv->lock); -		if (on) -			priv->control_state |= TIOCM_DTR | TIOCM_RTS; -		else -			priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); -		control_state = priv->control_state; -		spin_unlock_irq(&priv->lock); -		mct_u232_set_modem_ctrl(port->serial, control_state); -	} -	mutex_unlock(&port->serial->disc_mutex); +	spin_lock_irq(&priv->lock); +	if (on) +		priv->control_state |= TIOCM_DTR | TIOCM_RTS; +	else +		priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); +	control_state = priv->control_state; +	spin_unlock_irq(&priv->lock); + +	mct_u232_set_modem_ctrl(port, control_state);  }  static void mct_u232_close(struct usb_serial_port *port)  { -	dbg("%s port %d", __func__, port->number); +	struct mct_u232_private *priv = usb_get_serial_port_data(port); -	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); -	} +	usb_kill_urb(priv->read_urb); +	usb_kill_urb(port->interrupt_in_urb); + +	usb_serial_generic_close(port);  } /* mct_u232_close */ @@ -562,8 +502,6 @@ static void mct_u232_read_int_callback(struct urb *urb)  {  	struct usb_serial_port *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 retval;  	int status = urb->status; @@ -577,36 +515,25 @@ static void mct_u232_read_int_callback(struct urb *urb)  	case -ENOENT:  	case -ESHUTDOWN:  		/* this urb is terminated, clean up */ -		dbg("%s - urb shutting down with status: %d", -		    __func__, status); +		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n", +			__func__, status);  		return;  	default: -		dbg("%s - nonzero urb status received: %d", -		    __func__, status); +		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n", +			__func__, status);  		goto exit;  	} -	if (!serial) { -		dbg("%s - bad serial pointer, exiting", __func__); -		return; -	} - -	dbg("%s - port %d", __func__, port->number); -	usb_serial_debug_data(debug, &port->dev, __func__, -					urb->actual_length, data); +	usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);  	/*  	 * Work-a-round: handle the 'usual' bulk-in pipe here  	 */  	if (urb->transfer_buffer_length > 2) {  		if (urb->actual_length) { -			tty = tty_port_tty_get(&port->port); -			if (tty) { -				tty_insert_flip_string(tty, data, -						urb->actual_length); -				tty_flip_buffer_push(tty); -			} -			tty_kref_put(tty); +			tty_insert_flip_string(&port->port, data, +					urb->actual_length); +			tty_flip_buffer_push(&port->port);  		}  		goto exit;  	} @@ -619,7 +546,9 @@ static void mct_u232_read_int_callback(struct urb *urb)  	priv->last_msr = data[MCT_U232_MSR_INDEX];  	/* Record Control Line states */ -	mct_u232_msr_to_state(&priv->control_state, priv->last_msr); +	mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr); + +	mct_u232_msr_to_icount(&port->icount, priv->last_msr);  #if 0  	/* Not yet handled. See belkin_sa.c for further information */ @@ -647,6 +576,7 @@ static void mct_u232_read_int_callback(struct urb *urb)  		tty_kref_put(tty);  	}  #endif +	wake_up_interruptible(&port->port.delta_msr_wait);  	spin_unlock_irqrestore(&priv->lock, flags);  exit:  	retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -662,7 +592,7 @@ static void mct_u232_set_termios(struct tty_struct *tty,  {  	struct usb_serial *serial = port->serial;  	struct mct_u232_private *priv = usb_get_serial_port_data(port); -	struct ktermios *termios = tty->termios; +	struct ktermios *termios = &tty->termios;  	unsigned int cflag = termios->c_cflag;  	unsigned int old_cflag = old_termios->c_cflag;  	unsigned long flags; @@ -684,18 +614,18 @@ static void mct_u232_set_termios(struct tty_struct *tty,  	/* reassert DTR and RTS on transition from B0 */  	if ((old_cflag & CBAUD) == B0) { -		dbg("%s: baud was B0", __func__); +		dev_dbg(&port->dev, "%s: baud was B0\n", __func__);  		control_state |= TIOCM_DTR | TIOCM_RTS; -		mct_u232_set_modem_ctrl(serial, control_state); +		mct_u232_set_modem_ctrl(port, control_state);  	}  	mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));  	if ((cflag & CBAUD) == B0) { -		dbg("%s: baud is B0", __func__); +		dev_dbg(&port->dev, "%s: baud is B0\n", __func__);  		/* Drop RTS and DTR */  		control_state &= ~(TIOCM_DTR | TIOCM_RTS); -		mct_u232_set_modem_ctrl(serial, control_state); +		mct_u232_set_modem_ctrl(port, control_state);  	}  	/* @@ -732,7 +662,7 @@ static void mct_u232_set_termios(struct tty_struct *tty,  	last_lcr |= (cflag & CSTOPB) ?  		MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1; -	mct_u232_set_line_ctrl(serial, last_lcr); +	mct_u232_set_line_ctrl(port, last_lcr);  	/* save off the modified port settings */  	spin_lock_irqsave(&priv->lock, flags); @@ -744,13 +674,10 @@ static void mct_u232_set_termios(struct tty_struct *tty,  static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)  {  	struct usb_serial_port *port = tty->driver_data; -	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", __func__, break_state); -  	spin_lock_irqsave(&priv->lock, flags);  	lcr = priv->last_lcr; @@ -758,19 +685,17 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)  		lcr |= MCT_U232_SET_BREAK;  	spin_unlock_irqrestore(&priv->lock, flags); -	mct_u232_set_line_ctrl(serial, lcr); +	mct_u232_set_line_ctrl(port, lcr);  } /* mct_u232_break_ctl */ -static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file) +static int mct_u232_tiocmget(struct tty_struct *tty)  {  	struct usb_serial_port *port = tty->driver_data;  	struct mct_u232_private *priv = usb_get_serial_port_data(port);  	unsigned int control_state;  	unsigned long flags; -	dbg("%s", __func__); -  	spin_lock_irqsave(&priv->lock, flags);  	control_state = priv->control_state;  	spin_unlock_irqrestore(&priv->lock, flags); @@ -778,17 +703,14 @@ static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file)  	return control_state;  } -static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file, +static int mct_u232_tiocmset(struct tty_struct *tty,  			      unsigned int set, unsigned int clear)  {  	struct usb_serial_port *port = tty->driver_data; -	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", __func__); -  	spin_lock_irqsave(&priv->lock, flags);  	control_state = priv->control_state; @@ -803,7 +725,7 @@ static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,  	priv->control_state = control_state;  	spin_unlock_irqrestore(&priv->lock, flags); -	return mct_u232_set_modem_ctrl(serial, control_state); +	return mct_u232_set_modem_ctrl(port, control_state);  }  static void mct_u232_throttle(struct tty_struct *tty) @@ -812,72 +734,38 @@ static void mct_u232_throttle(struct tty_struct *tty)  	struct mct_u232_private *priv = usb_get_serial_port_data(port);  	unsigned int control_state; -	dbg("%s - port %d", __func__, port->number); -  	spin_lock_irq(&priv->lock);  	priv->rx_flags |= THROTTLED;  	if (C_CRTSCTS(tty)) {  		priv->control_state &= ~TIOCM_RTS;  		control_state = priv->control_state;  		spin_unlock_irq(&priv->lock); -		(void) mct_u232_set_modem_ctrl(port->serial, control_state); +		mct_u232_set_modem_ctrl(port, control_state);  	} else {  		spin_unlock_irq(&priv->lock);  	}  } -  static void mct_u232_unthrottle(struct tty_struct *tty)  {  	struct usb_serial_port *port = tty->driver_data;  	struct mct_u232_private *priv = usb_get_serial_port_data(port);  	unsigned int control_state; -	dbg("%s - port %d", __func__, port->number); -  	spin_lock_irq(&priv->lock);  	if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {  		priv->rx_flags &= ~THROTTLED;  		priv->control_state |= TIOCM_RTS;  		control_state = priv->control_state;  		spin_unlock_irq(&priv->lock); -		(void) mct_u232_set_modem_ctrl(port->serial, control_state); +		mct_u232_set_modem_ctrl(port, control_state);  	} else {  		spin_unlock_irq(&priv->lock);  	}  } -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; -	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" -	       DRIVER_DESC "\n"); -	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_usb_serial_driver(serial_drivers, id_table);  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");  | 
