summaryrefslogtreecommitdiff
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-22 15:25:26 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-22 15:25:26 -0700
commit09091a4d5f2dd378dcf71de50b48cdacc58a8ac0 (patch)
treed50e37ebb5591fa1e723f32bde077dbdf726b78b /drivers/usb/serial
parent66f75a5d028beaf67c931435fdc3e7823125730c (diff)
parent3a1c2a82204f5376f484d82cb18189afc2145c77 (diff)
Merge 3.4-rc4 into usb-next.
This resolves the conflict in: drivers/usb/host/ehci-fsl.c And picks up loads of xhci bugfixes to make it easier for others to test with. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/console.c9
-rw-r--r--drivers/usb/serial/io_ti.c17
-rw-r--r--drivers/usb/serial/ipaq.c34
-rw-r--r--drivers/usb/serial/metro-usb.c83
-rw-r--r--drivers/usb/serial/mos7840.c202
-rw-r--r--drivers/usb/serial/option.c2
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c8
-rw-r--r--drivers/usb/serial/usb_wwan.c8
-rw-r--r--drivers/usb/serial/visor.c65
-rw-r--r--drivers/usb/serial/whiteheat.c544
10 files changed, 300 insertions, 672 deletions
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 1ee6b2ab0f89..b9cca6dcde07 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -113,7 +113,8 @@ static int usb_console_setup(struct console *co, char *options)
serial = usb_serial_get_by_index(co->index);
if (serial == NULL) {
/* no device is connected yet, sorry :( */
- err("No USB device connected to ttyUSB%i", co->index);
+ printk(KERN_ERR "No USB device connected to ttyUSB%i\n",
+ co->index);
return -ENODEV;
}
@@ -137,7 +138,7 @@ static int usb_console_setup(struct console *co, char *options)
tty = kzalloc(sizeof(*tty), GFP_KERNEL);
if (!tty) {
retval = -ENOMEM;
- err("no more memory");
+ dev_err(&port->dev, "no more memory\n");
goto reset_open_count;
}
kref_init(&tty->kref);
@@ -146,7 +147,7 @@ static int usb_console_setup(struct console *co, char *options)
tty->index = co->index;
if (tty_init_termios(tty)) {
retval = -ENOMEM;
- err("no more memory");
+ dev_err(&port->dev, "no more memory\n");
goto free_tty;
}
}
@@ -159,7 +160,7 @@ static int usb_console_setup(struct console *co, char *options)
retval = usb_serial_generic_open(NULL, port);
if (retval) {
- err("could not open USB console port");
+ dev_err(&port->dev, "could not open USB console port\n");
goto fail;
}
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 40a95a7fe383..5e4b47194819 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -547,6 +547,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
{
int baud_rate;
struct tty_struct *tty = tty_port_tty_get(&port->port->port);
+ struct usb_serial *serial = port->port->serial;
wait_queue_t wait;
unsigned long flags;
@@ -561,7 +562,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
set_current_state(TASK_INTERRUPTIBLE);
if (kfifo_len(&port->write_fifo) == 0
|| timeout == 0 || signal_pending(current)
- || !usb_get_intfdata(port->port->serial->interface))
+ || serial->disconnected)
/* disconnect */
break;
spin_unlock_irqrestore(&port->ep_lock, flags);
@@ -578,7 +579,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
/* wait for data to drain from the device */
timeout += jiffies;
while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
- && usb_get_intfdata(port->port->serial->interface)) {
+ && !serial->disconnected) {
/* not disconnected */
if (!tx_active(port))
break;
@@ -586,7 +587,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
}
/* disconnected */
- if (!usb_get_intfdata(port->port->serial->interface))
+ if (serial->disconnected)
return;
/* wait one more character time, based on baud rate */
@@ -2003,8 +2004,8 @@ static void edge_close(struct usb_serial_port *port)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
+ struct usb_serial *serial = port->serial;
int port_number;
- int status;
dbg("%s - port %d", __func__, port->number);
@@ -2028,12 +2029,18 @@ static void edge_close(struct usb_serial_port *port)
* send a close port command to it */
dbg("%s - send umpc_close_port", __func__);
port_number = port->number - port->serial->minor;
- status = send_cmd(port->serial->dev,
+
+ mutex_lock(&serial->disc_mutex);
+ if (!serial->disconnected) {
+ send_cmd(serial->dev,
UMPC_CLOSE_PORT,
(__u8)(UMPM_UART1_PORT + port_number),
0,
NULL,
0);
+ }
+ mutex_unlock(&serial->disc_mutex);
+
mutex_lock(&edge_serial->es_lock);
--edge_port->edge_serial->num_ports_open;
if (edge_port->edge_serial->num_ports_open <= 0) {
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 10c02b8b5664..61e200ffe6b4 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -33,7 +33,6 @@
#define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"
#define DRIVER_DESC "USB PocketPC PDA driver"
-static __u16 product, vendor;
static bool debug;
static int connect_retries = KP_RETRIES;
static int initial_wait;
@@ -45,8 +44,6 @@ static int ipaq_calc_num_ports(struct usb_serial *serial);
static int ipaq_startup(struct usb_serial *serial);
static struct usb_device_id ipaq_id_table [] = {
- /* The first entry is a placeholder for the insmod-specified device */
- { USB_DEVICE(0x049F, 0x0003) },
{ USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */
{ USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */
{ USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */
@@ -623,30 +620,7 @@ static int ipaq_startup(struct usb_serial *serial)
return usb_reset_configuration(serial->dev);
}
-static int __init ipaq_init(void)
-{
- int retval;
-
- if (vendor) {
- ipaq_id_table[0].idVendor = vendor;
- ipaq_id_table[0].idProduct = product;
- }
-
- retval = usb_serial_register_drivers(&ipaq_driver, serial_drivers);
- if (retval == 0)
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
- return retval;
-}
-
-static void __exit ipaq_exit(void)
-{
- usb_serial_deregister_drivers(&ipaq_driver, serial_drivers);
-}
-
-
-module_init(ipaq_init);
-module_exit(ipaq_exit);
+module_usb_serial_driver(ipaq_driver, serial_drivers);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
@@ -655,12 +629,6 @@ MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-module_param(vendor, ushort, 0);
-MODULE_PARM_DESC(vendor, "User specified USB idVendor");
-
-module_param(product, ushort, 0);
-MODULE_PARM_DESC(product, "User specified USB idProduct");
-
module_param(connect_retries, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(connect_retries,
"Maximum number of connect retries (one second each)");
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c
index 08d16e8c002d..d17c8677a293 100644
--- a/drivers/usb/serial/metro-usb.c
+++ b/drivers/usb/serial/metro-usb.c
@@ -17,7 +17,6 @@
#include <linux/tty_flip.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
-#include <linux/errno.h>
#include <linux/uaccess.h>
#include <linux/usb/serial.h>
@@ -56,6 +55,47 @@ MODULE_DEVICE_TABLE(usb, id_table);
/* Input parameter constants. */
static bool debug;
+/* UNI-Directional mode commands for device configure */
+#define UNI_CMD_OPEN 0x80
+#define UNI_CMD_CLOSE 0xFF
+
+inline int metrousb_is_unidirectional_mode(struct usb_serial_port *port)
+{
+ __u16 product_id = le16_to_cpu(
+ port->serial->dev->descriptor.idProduct);
+
+ return product_id == FOCUS_PRODUCT_ID_UNI;
+}
+
+static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port)
+{
+ int ret;
+ int actual_len;
+ u8 *buffer_cmd = NULL;
+
+ if (!metrousb_is_unidirectional_mode(port))
+ return 0;
+
+ buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL);
+ if (!buffer_cmd)
+ return -ENOMEM;
+
+ *buffer_cmd = cmd;
+
+ ret = usb_interrupt_msg(port->serial->dev,
+ usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
+ buffer_cmd, sizeof(cmd),
+ &actual_len, USB_CTRL_SET_TIMEOUT);
+
+ kfree(buffer_cmd);
+
+ if (ret < 0)
+ return ret;
+ else if (actual_len != sizeof(cmd))
+ return -EIO;
+ return 0;
+}
+
static void metrousb_read_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
@@ -78,12 +118,12 @@ static void metrousb_read_int_callback(struct urb *urb)
/* urb has been terminated. */
dev_dbg(&port->dev,
"%s - urb shutting down, error code=%d\n",
- __func__, result);
+ __func__, urb->status);
return;
default:
dev_dbg(&port->dev,
"%s - non-zero urb received, error code=%d\n",
- __func__, result);
+ __func__, urb->status);
goto exit;
}
@@ -91,7 +131,7 @@ static void metrousb_read_int_callback(struct urb *urb)
/* Set the data read from the usb port into the serial port buffer. */
tty = tty_port_tty_get(&port->port);
if (!tty) {
- dev_dbg(&port->dev, "%s - bad tty pointer - exiting\n",
+ dev_err(&port->dev, "%s - bad tty pointer - exiting\n",
__func__);
return;
}
@@ -121,7 +161,7 @@ static void metrousb_read_int_callback(struct urb *urb)
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
- dev_dbg(&port->dev,
+ dev_err(&port->dev,
"%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
}
@@ -131,11 +171,19 @@ exit:
/* Try to resubmit the urb. */
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result)
- dev_dbg(&port->dev,
+ dev_err(&port->dev,
"%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
}
+static void metrousb_write_int_callback(struct urb *urb)
+{
+ struct usb_serial_port *port = urb->context;
+
+ dev_warn(&port->dev, "%s not implemented yet.\n",
+ __func__);
+}
+
static void metrousb_cleanup(struct usb_serial_port *port)
{
dev_dbg(&port->dev, "%s\n", __func__);
@@ -146,6 +194,9 @@ static void metrousb_cleanup(struct usb_serial_port *port)
usb_unlink_urb(port->interrupt_in_urb);
usb_kill_urb(port->interrupt_in_urb);
}
+
+ /* Send deactivate cmd to device */
+ metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port);
}
}
@@ -160,7 +211,7 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
/* Make sure the urb is initialized. */
if (!port->interrupt_in_urb) {
- dev_dbg(&port->dev, "%s - interrupt urb not initialized\n",
+ dev_err(&port->dev, "%s - interrupt urb not initialized\n",
__func__);
return -ENODEV;
}
@@ -191,12 +242,21 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result) {
- dev_dbg(&port->dev,
+ dev_err(&port->dev,
"%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
goto exit;
}
+ /* Send activate cmd to device */
+ result = metrousb_send_unidirectional_cmd(UNI_CMD_OPEN, port);
+ if (result) {
+ dev_err(&port->dev,
+ "%s - failed to configure device for port number=%d, error code=%d\n",
+ __func__, port->number, result);
+ goto exit;
+ }
+
dev_dbg(&port->dev, "%s - port open\n", __func__);
exit:
return result;
@@ -221,7 +281,7 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr
METROUSB_SET_REQUEST_TYPE, METROUSB_SET_MODEM_CTRL_REQUEST,
control_state, 0, NULL, 0, WDR_TIMEOUT);
if (retval < 0)
- dev_dbg(&serial->dev->dev,
+ dev_err(&serial->dev->dev,
"%s - set modem ctrl=0x%x failed, error code=%d\n",
__func__, mcr, retval);
@@ -354,7 +414,7 @@ static void metrousb_unthrottle(struct tty_struct *tty)
port->interrupt_in_urb->dev = port->serial->dev;
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
- dev_dbg(tty->dev,
+ dev_err(tty->dev,
"failed submitting interrupt in urb error code=%d\n",
result);
}
@@ -371,12 +431,13 @@ static struct usb_serial_driver metrousb_device = {
.owner = THIS_MODULE,
.name = "metro-usb",
},
- .description = "Metrologic USB to serial converter.",
+ .description = "Metrologic USB to Serial",
.id_table = id_table,
.num_ports = 1,
.open = metrousb_open,
.close = metrousb_cleanup,
.read_int_callback = metrousb_read_int_callback,
+ .write_int_callback = metrousb_write_int_callback,
.attach = metrousb_startup,
.release = metrousb_shutdown,
.throttle = metrousb_throttle,
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index c526550694a0..aaef523955e0 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -114,6 +114,7 @@
#define USB_VENDOR_ID_MOSCHIP 0x9710
#define MOSCHIP_DEVICE_ID_7840 0x7840
#define MOSCHIP_DEVICE_ID_7820 0x7820
+#define MOSCHIP_DEVICE_ID_7810 0x7810
/* The native component can have its vendor/device id's overridden
* in vendor-specific implementations. Such devices can be handled
* by making a change here, in moschip_port_id_table, and in
@@ -184,10 +185,16 @@
#define NUM_URBS 16 /* URB Count */
#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
+/* LED on/off milliseconds*/
+#define LED_ON_MS 500
+#define LED_OFF_MS 500
+
+static int device_type;
static const struct usb_device_id moschip_port_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+ {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
@@ -209,6 +216,7 @@ static const struct usb_device_id moschip_port_id_table[] = {
static const struct usb_device_id moschip_id_table_combined[] __devinitconst = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+ {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
@@ -261,8 +269,13 @@ struct moschip_port {
struct urb *write_urb_pool[NUM_URBS];
char busy[NUM_URBS];
bool read_urb_busy;
-};
+ /* For device(s) with LED indicator */
+ bool has_led;
+ bool led_flag;
+ struct timer_list led_timer1; /* Timer for LED on */
+ struct timer_list led_timer2; /* Timer for LED off */
+};
static bool debug;
@@ -572,6 +585,69 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
return ret;
}
+static void mos7840_set_led_callback(struct urb *urb)
+{
+ 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", __func__,
+ urb->status);
+ break;
+ default:
+ dbg("%s - nonzero urb status received: %d", __func__,
+ urb->status);
+ }
+}
+
+static void mos7840_set_led_async(struct moschip_port *mcs, __u16 wval,
+ __u16 reg)
+{
+ struct usb_device *dev = mcs->port->serial->dev;
+ struct usb_ctrlrequest *dr = mcs->dr;
+
+ dr->bRequestType = MCS_WR_RTYPE;
+ dr->bRequest = MCS_WRREQ;
+ dr->wValue = cpu_to_le16(wval);
+ dr->wIndex = cpu_to_le16(reg);
+ dr->wLength = cpu_to_le16(0);
+
+ usb_fill_control_urb(mcs->control_urb, dev, usb_sndctrlpipe(dev, 0),
+ (unsigned char *)dr, NULL, 0, mos7840_set_led_callback, NULL);
+
+ usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
+}
+
+static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg,
+ __u16 val)
+{
+ struct usb_device *dev = port->serial->dev;
+
+ usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, MCS_WR_RTYPE,
+ val, reg, NULL, 0, MOS_WDR_TIMEOUT);
+}
+
+static void mos7840_led_off(unsigned long arg)
+{
+ struct moschip_port *mcs = (struct moschip_port *) arg;
+
+ /* Turn off LED */
+ mos7840_set_led_async(mcs, 0x0300, MODEM_CONTROL_REGISTER);
+ mod_timer(&mcs->led_timer2,
+ jiffies + msecs_to_jiffies(LED_OFF_MS));
+}
+
+static void mos7840_led_flag_off(unsigned long arg)
+{
+ struct moschip_port *mcs = (struct moschip_port *) arg;
+
+ mcs->led_flag = false;
+}
+
/*****************************************************************************
* mos7840_interrupt_callback
* this is the callback function for when we have received data on the
@@ -792,6 +868,14 @@ static void mos7840_bulk_in_callback(struct urb *urb)
return;
}
+ /* Turn on LED */
+ if (mos7840_port->has_led && !mos7840_port->led_flag) {
+ mos7840_port->led_flag = true;
+ mos7840_set_led_async(mos7840_port, 0x0301,
+ MODEM_CONTROL_REGISTER);
+ mod_timer(&mos7840_port->led_timer1,
+ jiffies + msecs_to_jiffies(LED_ON_MS));
+ }
mos7840_port->read_urb_busy = true;
retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
@@ -1554,6 +1638,14 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
data1 = urb->transfer_buffer;
dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
+ /* Turn on LED */
+ if (mos7840_port->has_led && !mos7840_port->led_flag) {
+ mos7840_port->led_flag = true;
+ mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0301);
+ mod_timer(&mos7840_port->led_timer1,
+ jiffies + msecs_to_jiffies(LED_ON_MS));
+ }
+
/* send it down the pipe */
status = usb_submit_urb(urb, GFP_ATOMIC);
@@ -2327,28 +2419,74 @@ static int mos7840_ioctl(struct tty_struct *tty,
return -ENOIOCTLCMD;
}
+static int mos7810_check(struct usb_serial *serial)
+{
+ int i, pass_count = 0;
+ __u16 data = 0, mcr_data = 0;
+ __u16 test_pattern = 0x55AA;
+
+ /* Store MCR setting */
+ usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
+ &mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+
+ for (i = 0; i < 16; i++) {
+ /* Send the 1-bit test pattern out to MCS7810 test pin */
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ MCS_WRREQ, MCS_WR_RTYPE,
+ (0x0300 | (((test_pattern >> i) & 0x0001) << 1)),
+ MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
+
+ /* Read the test pattern back */
+ usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
+ VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+
+ /* If this is a MCS7810 device, both test patterns must match */
+ if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
+ break;
+
+ pass_count++;
+ }
+
+ /* Restore MCR setting */
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), MCS_WRREQ,
+ MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
+ 0, MOS_WDR_TIMEOUT);
+
+ if (pass_count == 16)
+ return 1;
+
+ return 0;
+}
+
static int mos7840_calc_num_ports(struct usb_serial *serial)
{
- __u16 Data = 0x00;
- int ret = 0;
+ __u16 data = 0x00;
int mos7840_num_ports;
- ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data,
+ usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
- if ((Data & 0x01) == 0) {
- mos7840_num_ports = 2;
- serial->num_bulk_in = 2;
- serial->num_bulk_out = 2;
- serial->num_ports = 2;
+ if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
+ serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
+ device_type = serial->dev->descriptor.idProduct;
} else {
- mos7840_num_ports = 4;
- serial->num_bulk_in = 4;
- serial->num_bulk_out = 4;
- serial->num_ports = 4;
+ /* For a MCS7840 device GPIO0 must be set to 1 */
+ if ((data & 0x01) == 1)
+ device_type = MOSCHIP_DEVICE_ID_7840;
+ else if (mos7810_check(serial))
+ device_type = MOSCHIP_DEVICE_ID_7810;
+ else
+ device_type = MOSCHIP_DEVICE_ID_7820;
}
+ mos7840_num_ports = (device_type >> 4) & 0x000F;
+ serial->num_bulk_in = mos7840_num_ports;
+ serial->num_bulk_out = mos7840_num_ports;
+ serial->num_ports = mos7840_num_ports;
+
return mos7840_num_ports;
}
@@ -2563,6 +2701,34 @@ static int mos7840_startup(struct usb_serial *serial)
status = -ENOMEM;
goto error;
}
+
+ mos7840_port->has_led = false;
+
+ /* Initialize LED timers */
+ if (device_type == MOSCHIP_DEVICE_ID_7810) {
+ mos7840_port->has_led = true;
+
+ init_timer(&mos7840_port->led_timer1);
+ mos7840_port->led_timer1.function = mos7840_led_off;
+ mos7840_port->led_timer1.expires =
+ jiffies + msecs_to_jiffies(LED_ON_MS);
+ mos7840_port->led_timer1.data =
+ (unsigned long)mos7840_port;
+
+ init_timer(&mos7840_port->led_timer2);
+ mos7840_port->led_timer2.function =
+ mos7840_led_flag_off;
+ mos7840_port->led_timer2.expires =
+ jiffies + msecs_to_jiffies(LED_OFF_MS);
+ mos7840_port->led_timer2.data =
+ (unsigned long)mos7840_port;
+
+ mos7840_port->led_flag = false;
+
+ /* Turn off LED */
+ mos7840_set_led_sync(serial->port[i],
+ MODEM_CONTROL_REGISTER, 0x0300);
+ }
}
dbg ("mos7840_startup: all ports configured...........");
@@ -2654,6 +2820,14 @@ static void mos7840_release(struct usb_serial *serial)
mos7840_port = mos7840_get_port_private(serial->port[i]);
dbg("mos7840_port %d = %p", i, mos7840_port);
if (mos7840_port) {
+ if (mos7840_port->has_led) {
+ /* Turn off LED */
+ mos7840_set_led_sync(mos7840_port->port,
+ MODEM_CONTROL_REGISTER, 0x0300);
+
+ del_timer_sync(&mos7840_port->led_timer1);
+ del_timer_sync(&mos7840_port->led_timer2);
+ }
kfree(mos7840_port->ctrl_buf);
kfree(mos7840_port->dr);
kfree(mos7840_port);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index f4465ccddc35..9ea5f4b39757 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1413,7 +1413,7 @@ static void option_instat_callback(struct urb *urb)
req_pkt->bRequestType, req_pkt->bRequest);
}
} else
- err("%s: error %d", __func__, status);
+ dev_err(&port->dev, "%s: error %d\n", __func__, status);
/* Resubmit urb so we continue receiving IRQ data */
if (status != -ESHUTDOWN && status != -ENOENT) {
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index ab74123d658e..82116f42e6fd 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -394,7 +394,9 @@ static int ti_startup(struct usb_serial *serial)
/* if we have only 1 configuration, download firmware */
if (dev->descriptor.bNumConfigurations == 1) {
- if ((status = ti_download_firmware(tdev)) != 0)
+ status = ti_download_firmware(tdev);
+
+ if (status != 0)
goto free_tdev;
/* 3410 must be reset, 5052 resets itself */
@@ -1683,7 +1685,9 @@ static int ti_download_firmware(struct ti_device *tdev)
/* try ID specific firmware first, then try generic firmware */
sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
dev->descriptor.idProduct);
- if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) {
+ status = request_firmware(&fw_p, buf, &dev->dev);
+
+ if (status != 0) {
buf[0] = '\0';
if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
switch (dev->descriptor.idProduct) {
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index c88657dd31c8..194c5461290d 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -725,8 +725,8 @@ int usb_wwan_resume(struct usb_serial *serial)
err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
dbg("Submitted interrupt URB for port %d (result %d)", i, err);
if (err < 0) {
- err("%s: Error %d for interrupt URB of port%d",
- __func__, err, i);
+ dev_err(&port->dev, "%s: Error %d for interrupt URB\n",
+ __func__, err);
goto err_out;
}
}
@@ -747,8 +747,8 @@ int usb_wwan_resume(struct usb_serial *serial)
urb = portdata->in_urbs[j];
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- err("%s: Error %d for bulk URB %d",
- __func__, err, i);
+ dev_err(&port->dev, "%s: Error %d for bulk URB %d\n",
+ __func__, err, i);
spin_unlock_irq(&intfdata->susp_lock);
goto err_out;
}
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 71d696474f24..aa8911dc4154 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -53,8 +53,6 @@ static int palm_os_4_probe(struct usb_serial *serial,
/* Parameters that may be passed into the module. */
static bool debug;
-static __u16 vendor;
-static __u16 product;
static struct usb_device_id id_table [] = {
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
@@ -115,14 +113,12 @@ static struct usb_device_id id_table [] = {
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
- { }, /* optional parameter entry */
{ } /* Terminating entry */
};
static struct usb_device_id clie_id_5_table [] = {
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
- { }, /* optional parameter entry */
{ } /* Terminating entry */
};
@@ -162,7 +158,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },
{ USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) },
- { }, /* optional parameter entry */
{ } /* Terminating entry */
};
@@ -648,59 +643,7 @@ static int clie_5_attach(struct usb_serial *serial)
return 0;
}
-static int __init visor_init(void)
-{
- int i, retval;
- /* Only if parameters were passed to us */
- if (vendor > 0 && product > 0) {
- struct usb_device_id usb_dev_temp[] = {
- {
- USB_DEVICE(vendor, product),
- .driver_info =
- (kernel_ulong_t) &palm_os_4_probe
- }
- };
-
- /* Find the last entry in id_table */
- for (i = 0;; i++) {
- if (id_table[i].idVendor == 0) {
- id_table[i] = usb_dev_temp[0];
- break;
- }
- }
- /* Find the last entry in id_table_combined */
- for (i = 0;; i++) {
- if (id_table_combined[i].idVendor == 0) {
- id_table_combined[i] = usb_dev_temp[0];
- break;
- }
- }
- printk(KERN_INFO KBUILD_MODNAME
- ": Untested USB device specified at time of module insertion\n");
- printk(KERN_INFO KBUILD_MODNAME
- ": Warning: This is not guaranteed to work\n");
- printk(KERN_INFO KBUILD_MODNAME
- ": Using a newer kernel is preferred to this method\n");
- printk(KERN_INFO KBUILD_MODNAME
- ": Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x\n",
- vendor, product);
- }
-
- retval = usb_serial_register_drivers(&visor_driver, serial_drivers);
- if (retval == 0)
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
- return retval;
-}
-
-
-static void __exit visor_exit (void)
-{
- usb_serial_deregister_drivers(&visor_driver, serial_drivers);
-}
-
-
-module_init(visor_init);
-module_exit(visor_exit);
+module_usb_serial_driver(visor_driver, serial_drivers);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
@@ -708,9 +651,3 @@ MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-module_param(vendor, ushort, 0);
-MODULE_PARM_DESC(vendor, "User specified vendor ID");
-module_param(product, ushort, 0);
-MODULE_PARM_DESC(product, "User specified product ID");
-
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 407e23c87946..c141b472b6a2 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -45,7 +45,6 @@ static bool debug;
/*
* Version Information
*/
-#define DRIVER_VERSION "v2.0"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Stuart MacDonald <stuartm@connecttech.com>"
#define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
@@ -96,10 +95,6 @@ static void whiteheat_release(struct usb_serial *serial);
static int whiteheat_open(struct tty_struct *tty,
struct usb_serial_port *port);
static void whiteheat_close(struct usb_serial_port *port);
-static int whiteheat_write(struct tty_struct *tty,
- struct usb_serial_port *port,
- const unsigned char *buf, int count);
-static int whiteheat_write_room(struct tty_struct *tty);
static int whiteheat_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg);
static void whiteheat_set_termios(struct tty_struct *tty,
@@ -108,11 +103,6 @@ static int whiteheat_tiocmget(struct tty_struct *tty);
static int whiteheat_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
-static int whiteheat_chars_in_buffer(struct tty_struct *tty);
-static void whiteheat_throttle(struct tty_struct *tty);
-static void whiteheat_unthrottle(struct tty_struct *tty);
-static void whiteheat_read_callback(struct urb *urb);
-static void whiteheat_write_callback(struct urb *urb);
static struct usb_serial_driver whiteheat_fake_device = {
.driver = {
@@ -138,18 +128,13 @@ static struct usb_serial_driver whiteheat_device = {
.release = whiteheat_release,
.open = whiteheat_open,
.close = whiteheat_close,
- .write = whiteheat_write,
- .write_room = whiteheat_write_room,
.ioctl = whiteheat_ioctl,
.set_termios = whiteheat_set_termios,
.break_ctl = whiteheat_break_ctl,
.tiocmget = whiteheat_tiocmget,
.tiocmset = whiteheat_tiocmset,
- .chars_in_buffer = whiteheat_chars_in_buffer,
- .throttle = whiteheat_throttle,
- .unthrottle = whiteheat_unthrottle,
- .read_bulk_callback = whiteheat_read_callback,
- .write_bulk_callback = whiteheat_write_callback,
+ .throttle = usb_serial_generic_throttle,
+ .unthrottle = usb_serial_generic_unthrottle,
};
static struct usb_serial_driver * const serial_drivers[] = {
@@ -166,29 +151,8 @@ struct whiteheat_command_private {
__u8 result_buffer[64];
};
-
-#define THROTTLED 0x01
-#define ACTUALLY_THROTTLED 0x02
-
-static int urb_pool_size = 8;
-
-struct whiteheat_urb_wrap {
- struct list_head list;
- struct urb *urb;
-};
-
struct whiteheat_private {
- spinlock_t lock;
- __u8 flags;
__u8 mcr; /* FIXME: no locking on mcr */
- struct list_head rx_urbs_free;
- struct list_head rx_urbs_submitted;
- struct list_head rx_urb_q;
- struct work_struct rx_work;
- struct usb_serial_port *port;
- struct list_head tx_urbs_free;
- struct list_head tx_urbs_submitted;
- struct mutex deathwarrant;
};
@@ -198,12 +162,6 @@ static void stop_command_port(struct usb_serial *serial);
static void command_port_write_callback(struct urb *urb);
static void command_port_read_callback(struct urb *urb);
-static int start_port_read(struct usb_serial_port *port);
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
- struct list_head *head);
-static struct list_head *list_first(struct list_head *head);
-static void rx_data_softint(struct work_struct *work);
-
static int firm_send_command(struct usb_serial_port *port, __u8 command,
__u8 *data, __u8 datasize);
static int firm_open(struct usb_serial_port *port);
@@ -349,11 +307,6 @@ static int whiteheat_attach(struct usb_serial *serial)
__u8 *command;
__u8 *result;
int i;
- int j;
- struct urb *urb;
- int buf_size;
- struct whiteheat_urb_wrap *wrap;
- struct list_head *tmp;
command_port = serial->port[COMMAND_PORT];
@@ -408,8 +361,8 @@ static int whiteheat_attach(struct usb_serial *serial)
hw_info = (struct whiteheat_hw_info *)&result[1];
- dev_info(&serial->dev->dev, "%s: Driver %s: Firmware v%d.%02d\n",
- serial->type->description, DRIVER_VERSION,
+ dev_info(&serial->dev->dev, "%s: Firmware v%d.%02d\n",
+ serial->type->description,
hw_info->sw_major_rev, hw_info->sw_minor_rev);
for (i = 0; i < serial->num_ports; i++) {
@@ -423,72 +376,7 @@ static int whiteheat_attach(struct usb_serial *serial)
goto no_private;
}
- spin_lock_init(&info->lock);
- mutex_init(&info->deathwarrant);
- info->flags = 0;
info->mcr = 0;
- INIT_WORK(&info->rx_work, rx_data_softint);
- info->port = port;
-
- INIT_LIST_HEAD(&info->rx_urbs_free);
- INIT_LIST_HEAD(&info->rx_urbs_submitted);
- INIT_LIST_HEAD(&info->rx_urb_q);
- INIT_LIST_HEAD(&info->tx_urbs_free);
- INIT_LIST_HEAD(&info->tx_urbs_submitted);
-
- for (j = 0; j < urb_pool_size; j++) {
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- dev_err(&port->dev, "No free urbs available\n");
- goto no_rx_urb;
- }
- buf_size = port->read_urb->transfer_buffer_length;
- urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
- if (!urb->transfer_buffer) {
- dev_err(&port->dev,
- "Couldn't allocate urb buffer\n");
- goto no_rx_buf;
- }
- wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
- if (!wrap) {
- dev_err(&port->dev,
- "Couldn't allocate urb wrapper\n");
- goto no_rx_wrap;
- }
- usb_fill_bulk_urb(urb, serial->dev,
- usb_rcvbulkpipe(serial->dev,
- port->bulk_in_endpointAddress),
- urb->transfer_buffer, buf_size,
- whiteheat_read_callback, port);
- wrap->urb = urb;
- list_add(&wrap->list, &info->rx_urbs_free);
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- dev_err(&port->dev, "No free urbs available\n");
- goto no_tx_urb;
- }
- buf_size = port->write_urb->transfer_buffer_length;
- urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
- if (!urb->transfer_buffer) {
- dev_err(&port->dev,
- "Couldn't allocate urb buffer\n");
- goto no_tx_buf;
- }
- wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
- if (!wrap) {
- dev_err(&port->dev,
- "Couldn't allocate urb wrapper\n");
- goto no_tx_wrap;
- }
- usb_fill_bulk_urb(urb, serial->dev,
- usb_sndbulkpipe(serial->dev,
- port->bulk_out_endpointAddress),
- urb->transfer_buffer, buf_size,
- whiteheat_write_callback, port);
- wrap->urb = urb;
- list_add(&wrap->list, &info->tx_urbs_free);
- }
usb_set_serial_port_data(port, info);
}
@@ -531,29 +419,6 @@ no_command_private:
for (i = serial->num_ports - 1; i >= 0; i--) {
port = serial->port[i];
info = usb_get_serial_port_data(port);
- for (j = urb_pool_size - 1; j >= 0; j--) {
- tmp = list_first(&info->tx_urbs_free);
- list_del(tmp);
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- kfree(wrap);
-no_tx_wrap:
- kfree(urb->transfer_buffer);
-no_tx_buf:
- usb_free_urb(urb);
-no_tx_urb:
- tmp = list_first(&info->rx_urbs_free);
- list_del(tmp);
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- kfree(wrap);
-no_rx_wrap:
- kfree(urb->transfer_buffer);
-no_rx_buf:
- usb_free_urb(urb);
-no_rx_urb:
- ;
- }
kfree(info);
no_private:
;
@@ -569,12 +434,7 @@ no_command_buffer:
static void whiteheat_release(struct usb_serial *serial)
{
struct usb_serial_port *command_port;
- struct usb_serial_port *port;
struct whiteheat_private *info;
- struct whiteheat_urb_wrap *wrap;
- struct urb *urb;
- struct list_head *tmp;
- struct list_head *tmp2;
int i;
dbg("%s", __func__);
@@ -584,31 +444,14 @@ static void whiteheat_release(struct usb_serial *serial)
kfree(usb_get_serial_port_data(command_port));
for (i = 0; i < serial->num_ports; i++) {
- port = serial->port[i];
- info = usb_get_serial_port_data(port);
- list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
- list_del(tmp);
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- kfree(wrap);
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
- list_for_each_safe(tmp, tmp2, &info->tx_urbs_free) {
- list_del(tmp);
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- kfree(wrap);
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
+ info = usb_get_serial_port_data(serial->port[i]);
kfree(info);
}
}
static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
{
- int retval = 0;
+ int retval;
dbg("%s - port %d", __func__, port->number);
@@ -616,9 +459,6 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
if (retval)
goto exit;
- if (tty)
- tty->low_latency = 1;
-
/* send an open port command */
retval = firm_open(port);
if (retval) {
@@ -640,17 +480,12 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
usb_clear_halt(port->serial->dev, port->read_urb->pipe);
usb_clear_halt(port->serial->dev, port->write_urb->pipe);
- /* Start reading from the device */
- retval = start_port_read(port);
+ retval = usb_serial_generic_open(tty, port);
if (retval) {
- dev_err(&port->dev,
- "%s - failed submitting read urb, error %d\n",
- __func__, retval);
firm_close(port);
stop_command_port(port->serial);
goto exit;
}
-
exit:
dbg("%s - exit, retval = %d", __func__, retval);
return retval;
@@ -659,125 +494,14 @@ exit:
static void whiteheat_close(struct usb_serial_port *port)
{
- struct whiteheat_private *info = usb_get_serial_port_data(port);
- struct whiteheat_urb_wrap *wrap;
- struct urb *urb;
- struct list_head *tmp;
- struct list_head *tmp2;
-
dbg("%s - port %d", __func__, port->number);
firm_report_tx_done(port);
firm_close(port);
- /* shutdown our bulk reads and writes */
- mutex_lock(&info->deathwarrant);
- spin_lock_irq(&info->lock);
- list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- list_del(tmp);
- spin_unlock_irq(&info->lock);
- usb_kill_urb(urb);
- spin_lock_irq(&info->lock);
- list_add(tmp, &info->rx_urbs_free);
- }
- list_for_each_safe(tmp, tmp2, &info->rx_urb_q)
- list_move(tmp, &info->rx_urbs_free);
- list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) {
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- list_del(tmp);
- spin_unlock_irq(&info->lock);
- usb_kill_urb(urb);
- spin_lock_irq(&info->lock);
- list_add(tmp, &info->tx_urbs_free);
- }
- spin_unlock_irq(&info->lock);
- mutex_unlock(&info->deathwarrant);
- stop_command_port(port->serial);
-}
-
-
-static int whiteheat_write(struct tty_struct *tty,
- struct usb_serial_port *port, const unsigned char *buf, int count)
-{
- struct whiteheat_private *info = usb_get_serial_port_data(port);
- struct whiteheat_urb_wrap *wrap;
- struct urb *urb;
- int result;
- int bytes;
- int sent = 0;
- unsigned long flags;
- struct list_head *tmp;
-
- dbg("%s - port %d", __func__, port->number);
-
- if (count == 0) {
- dbg("%s - write request of 0 bytes", __func__);
- return (0);
- }
-
- while (count) {
- spin_lock_irqsave(&info->lock, flags);
- if (list_empty(&info->tx_urbs_free)) {
- spin_unlock_irqrestore(&info->lock, flags);
- break;
- }
- tmp = list_first(&info->tx_urbs_free);
- list_del(tmp);
- spin_unlock_irqrestore(&info->lock, flags);
-
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- bytes = (count > port->bulk_out_size) ?
- port->bulk_out_size : count;
- memcpy(urb->transfer_buffer, buf + sent, bytes);
-
- usb_serial_debug_data(debug, &port->dev,
- __func__, bytes, urb->transfer_buffer);
-
- urb->transfer_buffer_length = bytes;
- result = usb_submit_urb(urb, GFP_ATOMIC);
- if (result) {
- dev_err_console(port,
- "%s - failed submitting write urb, error %d\n",
- __func__, result);
- sent = result;
- spin_lock_irqsave(&info->lock, flags);
- list_add(tmp, &info->tx_urbs_free);
- spin_unlock_irqrestore(&info->lock, flags);
- break;
- } else {
- sent += bytes;
- count -= bytes;
- spin_lock_irqsave(&info->lock, flags);
- list_add(tmp, &info->tx_urbs_submitted);
- spin_unlock_irqrestore(&info->lock, flags);
- }
- }
+ usb_serial_generic_close(port);
- return sent;
-}
-
-static int whiteheat_write_room(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct whiteheat_private *info = usb_get_serial_port_data(port);
- struct list_head *tmp;
- int room = 0;
- unsigned long flags;
-
- dbg("%s - port %d", __func__, port->number);
-
- spin_lock_irqsave(&info->lock, flags);
- list_for_each(tmp, &info->tx_urbs_free)
- room++;
- spin_unlock_irqrestore(&info->lock, flags);
- room *= port->bulk_out_size;
-
- dbg("%s - returns %d", __func__, room);
- return (room);
+ stop_command_port(port->serial);
}
static int whiteheat_tiocmget(struct tty_struct *tty)
@@ -837,7 +561,7 @@ static int whiteheat_ioctl(struct tty_struct *tty,
serstruct.line = port->serial->minor;
serstruct.port = port->number;
serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
- serstruct.xmit_fifo_size = port->bulk_out_size;
+ serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo);
serstruct.custom_divisor = 0;
serstruct.baud_base = 460800;
serstruct.close_delay = CLOSING_DELAY;
@@ -867,60 +591,6 @@ static void whiteheat_break_ctl(struct tty_struct *tty, int break_state)
}
-static int whiteheat_chars_in_buffer(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct whiteheat_private *info = usb_get_serial_port_data(port);
- struct list_head *tmp;
- struct whiteheat_urb_wrap *wrap;
- int chars = 0;
- unsigned long flags;
-
- dbg("%s - port %d", __func__, port->number);
-
- spin_lock_irqsave(&info->lock, flags);
- list_for_each(tmp, &info->tx_urbs_submitted) {
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- chars += wrap->urb->transfer_buffer_length;
- }
- spin_unlock_irqrestore(&info->lock, flags);
-
- dbg("%s - returns %d", __func__, chars);
- return chars;
-}
-
-
-static void whiteheat_throttle(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct whiteheat_private *info = usb_get_serial_port_data(port);
-
- dbg("%s - port %d", __func__, port->number);
-
- spin_lock_irq(&info->lock);
- info->flags |= THROTTLED;
- spin_unlock_irq(&info->lock);
-}
-
-
-static void whiteheat_unthrottle(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct whiteheat_private *info = usb_get_serial_port_data(port);
- int actually_throttled;
-
- dbg("%s - port %d", __func__, port->number);
-
- spin_lock_irq(&info->lock);
- actually_throttled = info->flags & ACTUALLY_THROTTLED;
- info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
- spin_unlock_irq(&info->lock);
-
- if (actually_throttled)
- rx_data_softint(&info->rx_work);
-}
-
-
/*****************************************************************************
* Connect Tech's White Heat callback routines
*****************************************************************************/
@@ -989,80 +659,6 @@ static void command_port_read_callback(struct urb *urb)
}
-static void whiteheat_read_callback(struct urb *urb)
-{
- struct usb_serial_port *port = urb->context;
- struct whiteheat_urb_wrap *wrap;
- unsigned char *data = urb->transfer_buffer;
- struct whiteheat_private *info = usb_get_serial_port_data(port);
- int status = urb->status;
-
- dbg("%s - port %d", __func__, port->number);
-
- spin_lock(&info->lock);
- wrap = urb_to_wrap(urb, &info->rx_urbs_submitted);
- if (!wrap) {
- spin_unlock(&info->lock);
- dev_err(&port->dev, "%s - Not my urb!\n", __func__);
- return;
- }
- list_del(&wrap->list);
- spin_unlock(&info->lock);
-
- if (status) {
- dbg("%s - nonzero read bulk status received: %d",
- __func__, status);
- spin_lock(&info->lock);
- list_add(&wrap->list, &info->rx_urbs_free);
- spin_unlock(&info->lock);
- return;
- }
-
- usb_serial_debug_data(debug, &port->dev,
- __func__, urb->actual_length, data);
-
- spin_lock(&info->lock);
- list_add_tail(&wrap->list, &info->rx_urb_q);
- if (info->flags & THROTTLED) {
- info->flags |= ACTUALLY_THROTTLED;
- spin_unlock(&info->lock);
- return;
- }
- spin_unlock(&info->lock);
-
- schedule_work(&info->rx_work);
-}
-
-
-static void whiteheat_write_callback(struct urb *urb)
-{
- struct usb_serial_port *port = urb->context;
- struct whiteheat_private *info = usb_get_serial_port_data(port);
- struct whiteheat_urb_wrap *wrap;
- int status = urb->status;
-
- dbg("%s - port %d", __func__, port->number);
-
- spin_lock(&info->lock);
- wrap = urb_to_wrap(urb, &info->tx_urbs_submitted);
- if (!wrap) {
- spin_unlock(&info->lock);
- dev_err(&port->dev, "%s - Not my urb!\n", __func__);
- return;
- }
- list_move(&wrap->list, &info->tx_urbs_free);
- spin_unlock(&info->lock);
-
- if (status) {
- dbg("%s - nonzero write bulk status received: %d",
- __func__, status);
- return;
- }
-
- usb_serial_port_softint(port);
-}
-
-
/*****************************************************************************
* Connect Tech's White Heat firmware interface
*****************************************************************************/
@@ -1337,123 +933,6 @@ static void stop_command_port(struct usb_serial *serial)
mutex_unlock(&command_info->mutex);
}
-
-static int start_port_read(struct usb_serial_port *port)
-{
- struct whiteheat_private *info = usb_get_serial_port_data(port);
- struct whiteheat_urb_wrap *wrap;
- struct urb *urb;
- int retval = 0;
- unsigned long flags;
- struct list_head *tmp;
- struct list_head *tmp2;
-
- spin_lock_irqsave(&info->lock, flags);
-
- list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
- list_del(tmp);
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- spin_unlock_irqrestore(&info->lock, flags);
- retval = usb_submit_urb(urb, GFP_KERNEL);
- if (retval) {
- spin_lock_irqsave(&info->lock, flags);
- list_add(tmp, &info->rx_urbs_free);
- list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
- list_del(tmp);
- spin_unlock_irqrestore(&info->lock, flags);
- usb_kill_urb(urb);
- spin_lock_irqsave(&info->lock, flags);
- list_add(tmp, &info->rx_urbs_free);
- }
- break;
- }
- spin_lock_irqsave(&info->lock, flags);
- list_add(tmp, &info->rx_urbs_submitted);
- }
-
- spin_unlock_irqrestore(&info->lock, flags);
-
- return retval;
-}
-
-
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
- struct list_head *head)
-{
- struct whiteheat_urb_wrap *wrap;
- struct list_head *tmp;
-
- list_for_each(tmp, head) {
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- if (wrap->urb == urb)
- return wrap;
- }
-
- return NULL;
-}
-
-
-static struct list_head *list_first(struct list_head *head)
-{
- return head->next;
-}
-
-
-static void rx_data_softint(struct work_struct *work)
-{
- struct whiteheat_private *info =
- container_of(work, struct whiteheat_private, rx_work);
- struct usb_serial_port *port = info->port;
- struct tty_struct *tty = tty_port_tty_get(&port->port);
- struct whiteheat_urb_wrap *wrap;
- struct urb *urb;
- unsigned long flags;
- struct list_head *tmp;
- struct list_head *tmp2;
- int result;
- int sent = 0;
-
- spin_lock_irqsave(&info->lock, flags);
- if (info->flags & THROTTLED) {
- spin_unlock_irqrestore(&info->lock, flags);
- goto out;
- }
-
- list_for_each_safe(tmp, tmp2, &info->rx_urb_q) {
- list_del(tmp);
- spin_unlock_irqrestore(&info->lock, flags);
-
- wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
- urb = wrap->urb;
-
- if (tty && urb->actual_length)
- sent += tty_insert_flip_string(tty,
- urb->transfer_buffer, urb->actual_length);
-
- result = usb_submit_urb(urb, GFP_ATOMIC);
- if (result) {
- dev_err(&port->dev,
- "%s - failed resubmitting read urb, error %d\n",
- __func__, result);
- spin_lock_irqsave(&info->lock, flags);
- list_add(tmp, &info->rx_urbs_free);
- continue;
- }
-
- spin_lock_irqsave(&info->lock, flags);
- list_add(tmp, &info->rx_urbs_submitted);
- }
- spin_unlock_irqrestore(&info->lock, flags);
-
- if (sent)
- tty_flip_buffer_push(tty);
-out:
- tty_kref_put(tty);
-}
-
module_usb_serial_driver(whiteheat_driver, serial_drivers);
MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -1463,8 +942,5 @@ MODULE_LICENSE("GPL");
MODULE_FIRMWARE("whiteheat.fw");
MODULE_FIRMWARE("whiteheat_loader.fw");
-module_param(urb_pool_size, int, 0);
-MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering");
-
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");