#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-
-#ifdef CONFIG_USB_SERIAL_DEBUG
- static int debug = 1;
-#else
- static int debug;
-#endif
-
#include "usb-serial.h"
#include "mct_u232.h"
-
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.2"
+#define DRIVER_VERSION "z2.0" /* Linux in-kernel version */
#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
-/*
- * Some not properly written applications do not handle the return code of
- * write() correctly. This can result in character losses. A work-a-round
- * can be compiled in with the following definition. This work-a-round
- * should _NOT_ be part of an 'official' kernel release, of course!
- */
-#undef FIX_WRITE_RETURN_CODE_PROBLEM
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-static int write_blocking; /* disabled by default */
-#endif
+static int debug;
/*
* Function prototypes
struct file *filp);
static void mct_u232_close (struct usb_serial_port *port,
struct file *filp);
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-static int mct_u232_write (struct usb_serial_port *port,
- int from_user,
- const unsigned char *buf,
- int count);
-static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-#endif
static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs);
static void mct_u232_set_termios (struct usb_serial_port *port,
struct termios * old);
MODULE_DEVICE_TABLE (usb, id_table_combined);
static struct usb_driver mct_u232_driver = {
- .owner = THIS_MODULE,
.name = "mct_u232",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table_combined,
+ .no_dynamic_id = 1,
};
-static struct usb_serial_device_type mct_u232_device = {
- .owner = THIS_MODULE,
- .name = "Magic Control Technology USB-RS232",
- .short_name = "mct_u232",
+static struct usb_serial_driver mct_u232_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "mct_u232",
+ },
+ .description = "MCT U232",
.id_table = id_table_combined,
.num_interrupt_in = 2,
.num_bulk_in = 0,
.num_ports = 1,
.open = mct_u232_open,
.close = mct_u232_close,
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
- .write = mct_u232_write,
- .write_bulk_callback = mct_u232_write_bulk_callback,
-#endif
.read_int_callback = mct_u232_read_int_callback,
.ioctl = mct_u232_ioctl,
.set_termios = mct_u232_set_termios,
* Handle vendor specific USB requests
*/
-#define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
+#define WDR_TIMEOUT 5000 /* default urb timeout */
/*
* Later day 2.6.0-test kernels have new baud rates like B230400 which
* we do not know how to support. We ignore them for the moment.
* XXX Rate-limit the error message, it's user triggerable.
*/
-static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
- if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
- || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
+static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value)
+{
+ if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
+ || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
switch (value) {
case B300: return 0x01;
case B600: return 0x02; /* this one not tested */
}
} else {
switch (value) {
- case B300: value = 300;
- case B600: value = 600;
- case B1200: value = 1200;
- case B2400: value = 2400;
- case B4800: value = 4800;
- case B9600: value = 9600;
- case B19200: value = 19200;
- case B38400: value = 38400;
- case B57600: value = 57600;
- case B115200: value = 115200;
+ case B300: value = 300; break;
+ case B600: value = 600; break;
+ case B1200: value = 1200; break;
+ case B2400: value = 2400; break;
+ case B4800: value = 4800; break;
+ case B9600: value = 9600; break;
+ case B19200: value = 19200; break;
+ case B38400: value = 38400; break;
+ case B57600: value = 57600; break;
+ case B115200: value = 115200; break;
default:
err("MCT USB-RS232: unsupported baudrate request 0x%x,"
" using default of B9600", value);
static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
{
- unsigned int divisor;
+ __le32 divisor;
int rc;
unsigned char zero_byte = 0;
struct mct_u232_private *priv;
struct usb_serial_port *port, *rport;
- /* allocate the private data structure */
priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- /* set initial values for control structures */
+ memset(priv, 0, sizeof(struct mct_u232_private));
spin_lock_init(&priv->lock);
- priv->control_state = 0;
- priv->last_lsr = 0;
- priv->last_msr = 0;
usb_set_serial_port_data(serial->port[0], priv);
init_waitqueue_head(&serial->port[0]->write_wait);
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]);
- if (priv)
+ if (priv) {
+ usb_set_serial_port_data(serial->port[i], NULL);
kfree(priv);
+ }
}
} /* mct_u232_shutdown */
* it seems to be able to accept only 16 bytes (and that's what
* SniffUSB says too...)
*/
- if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID)
+ 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
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");
+ 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");
+ err(" usb_submit_urb(read int) failed pipe 0x%x err %d",
+ port->interrupt_in_urb->pipe, retval);
exit:
return 0;
if (port->serial->dev) {
/* shutdown our urbs */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->read_urb);
- usb_unlink_urb (port->interrupt_in_urb);
+ usb_kill_urb(port->write_urb);
+ usb_kill_urb(port->read_urb);
+ usb_kill_urb(port->interrupt_in_urb);
}
} /* mct_u232_close */
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-/* The generic routines work fine otherwise */
-
-static int mct_u232_write (struct usb_serial_port *port, int from_user,
- const unsigned char *buf, int count)
-{
- struct usb_serial *serial = port->serial;
- int result, bytes_sent, size;
-
- dbg("%s - port %d", __FUNCTION__, port->number);
-
- if (count == 0) {
- dbg("%s - write request of 0 bytes", __FUNCTION__);
- return (0);
- }
-
- /* only do something if we have a bulk out endpoint */
- if (!serial->num_bulk_out)
- return(0);
-
- /* another write is still pending? */
- if (port->write_urb->status == -EINPROGRESS) {
- dbg("%s - already writing", __FUNCTION__);
- return (0);
- }
-
- bytes_sent = 0;
- while (count > 0) {
- size = (count > port->bulk_out_size) ? port->bulk_out_size : count;
-
- usb_serial_debug_data (__FILE__, __FUNCTION__, size, buf);
-
- if (from_user) {
- if (copy_from_user(port->write_urb->transfer_buffer, buf, size)) {
- return -EFAULT;
- }
- }
- else {
- memcpy (port->write_urb->transfer_buffer, buf, size);
- }
-
- /* set up our urb */
- usb_fill_bulk_urb(port->write_urb, serial->dev,
- usb_sndbulkpipe(serial->dev,
- port->bulk_out_endpointAddress),
- port->write_urb->transfer_buffer, size,
- ((serial->type->write_bulk_callback) ?
- serial->type->write_bulk_callback :
- mct_u232_write_bulk_callback),
- port);
-
- /* send the data out the bulk port */
- result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
- if (result) {
- err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
- return result;
- }
-
- bytes_sent += size;
- if (write_blocking)
- interruptible_sleep_on(&port->write_wait);
- else
- break;
-
- buf += size;
- count -= size;
- }
-
- return bytes_sent;
-} /* mct_u232_write */
-
-static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
-{
- struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
- struct usb_serial *serial = port->serial;
- struct tty_struct *tty = port->tty;
-
- dbg("%s - port %d", __FUNCTION__, port->number);
-
- if (!serial) {
- dbg("%s - bad serial pointer, exiting", __FUNCTION__);
- return;
- }
-
- if (urb->status) {
- dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
- urb->status);
- return;
- }
-
- if (write_blocking) {
- wake_up_interruptible(&port->write_wait);
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
- wake_up_interruptible(&tty->write_wait);
-
- } else {
- /* from generic_write_bulk_callback */
- schedule_work(&port->work);
- }
-
- return;
-} /* mct_u232_write_bulk_callback */
-#endif
-
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;
int status;
unsigned long flags;
- dbg("%s - port %d", __FUNCTION__, port->number);
-
switch (urb->status) {
case 0:
/* success */
dbg("%s - bad serial pointer, exiting", __FUNCTION__);
return;
}
-
- usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+
+ 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
else
new_state &= ~(TIOCM_DTR | TIOCM_RTS);
if (new_state != control_state) {
- mct_u232_set_modem_ctrl(serial, control_state);
+ mct_u232_set_modem_ctrl(serial, new_state);
control_state = new_state;
}
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-MODULE_PARM(write_blocking, "i");
-MODULE_PARM_DESC(write_blocking,
- "The write function will block to write out all data");
-#endif
-
-MODULE_PARM(debug, "i");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-