aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2010-12-16 13:05:06 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-12-16 13:05:06 -0500
commit36facadd9ea98f8415d0dbb63e0763b7ee9d3911 (patch)
tree99dea00b332ed852f2b0a4923b581dd723f03634 /drivers/usb/serial
parent2faa83e2a519abea1055d156ce1b42b8fa57e87b (diff)
parent0b83ae960cd7d4a5ee02786ecf41ab45688999bf (diff)
Merge branch 'usb-next' into musb-merge
* usb-next: (132 commits) USB: uas: Use GFP_NOIO instead of GFP_KERNEL in I/O submission path USB: uas: Ensure we only bind to a UAS interface USB: uas: Rename sense pipe and sense urb to status pipe and status urb USB: uas: Use kzalloc instead of kmalloc USB: uas: Fix up the Sense IU usb: musb: core: kill unneeded #include's DA8xx: assign name to MUSB IRQ resource usb: gadget: g_ncm added usb: gadget: f_ncm.c added usb: gadget: u_ether: prepare for NCM usb: pch_udc: Fix setup transfers with data out usb: pch_udc: Fix compile error, warnings and checkpatch warnings usb: add ab8500 usb transceiver driver USB: gadget: Implement runtime PM for MSM bus glue driver USB: gadget: Implement runtime PM for ci13xxx gadget USB: gadget: Add USB controller driver for MSM SoC USB: gadget: Introduce ci13xxx_udc_driver struct USB: gadget: Initialize ci13xxx gadget device's coherent DMA mask USB: gadget: Fix "scheduling while atomic" bugs in ci13xxx_udc USB: gadget: Separate out PCI bus code from ci13xxx_udc ...
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/option.c1
-rw-r--r--drivers/usb/serial/ssu100.c56
-rw-r--r--drivers/usb/serial/usb-wwan.h2
-rw-r--r--drivers/usb/serial/usb_wwan.c79
4 files changed, 90 insertions, 48 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index ef2977d3a613..cdfb1868caef 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -989,6 +989,7 @@ static struct usb_serial_driver option_1port_device = {
989 .set_termios = usb_wwan_set_termios, 989 .set_termios = usb_wwan_set_termios,
990 .tiocmget = usb_wwan_tiocmget, 990 .tiocmget = usb_wwan_tiocmget,
991 .tiocmset = usb_wwan_tiocmset, 991 .tiocmset = usb_wwan_tiocmset,
992 .ioctl = usb_wwan_ioctl,
992 .attach = usb_wwan_startup, 993 .attach = usb_wwan_startup,
993 .disconnect = usb_wwan_disconnect, 994 .disconnect = usb_wwan_disconnect,
994 .release = usb_wwan_release, 995 .release = usb_wwan_release,
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
index f5312dd3331b..8359ec798959 100644
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -79,7 +79,6 @@ struct ssu100_port_private {
79 u8 shadowLSR; 79 u8 shadowLSR;
80 u8 shadowMSR; 80 u8 shadowMSR;
81 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ 81 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
82 unsigned short max_packet_size;
83 struct async_icount icount; 82 struct async_icount icount;
84}; 83};
85 84
@@ -464,36 +463,6 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file,
464 return -ENOIOCTLCMD; 463 return -ENOIOCTLCMD;
465} 464}
466 465
467static void ssu100_set_max_packet_size(struct usb_serial_port *port)
468{
469 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
470 struct usb_serial *serial = port->serial;
471 struct usb_device *udev = serial->dev;
472
473 struct usb_interface *interface = serial->interface;
474 struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc;
475
476 unsigned num_endpoints;
477 int i;
478 unsigned long flags;
479
480 num_endpoints = interface->cur_altsetting->desc.bNumEndpoints;
481 dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints);
482
483 for (i = 0; i < num_endpoints; i++) {
484 dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1,
485 interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
486 ep_desc = &interface->cur_altsetting->endpoint[i].desc;
487 }
488
489 /* set max packet size based on descriptor */
490 spin_lock_irqsave(&priv->status_lock, flags);
491 priv->max_packet_size = ep_desc->wMaxPacketSize;
492 spin_unlock_irqrestore(&priv->status_lock, flags);
493
494 dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
495}
496
497static int ssu100_attach(struct usb_serial *serial) 466static int ssu100_attach(struct usb_serial *serial)
498{ 467{
499 struct ssu100_port_private *priv; 468 struct ssu100_port_private *priv;
@@ -511,7 +480,6 @@ static int ssu100_attach(struct usb_serial *serial)
511 spin_lock_init(&priv->status_lock); 480 spin_lock_init(&priv->status_lock);
512 init_waitqueue_head(&priv->delta_msr_wait); 481 init_waitqueue_head(&priv->delta_msr_wait);
513 usb_set_serial_port_data(port, priv); 482 usb_set_serial_port_data(port, priv);
514 ssu100_set_max_packet_size(port);
515 483
516 return ssu100_initdevice(serial->dev); 484 return ssu100_initdevice(serial->dev);
517} 485}
@@ -641,13 +609,14 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
641 609
642} 610}
643 611
644static int ssu100_process_packet(struct tty_struct *tty, 612static int ssu100_process_packet(struct urb *urb,
645 struct usb_serial_port *port, 613 struct tty_struct *tty)
646 struct ssu100_port_private *priv,
647 char *packet, int len)
648{ 614{
649 int i; 615 struct usb_serial_port *port = urb->context;
616 char *packet = (char *)urb->transfer_buffer;
650 char flag = TTY_NORMAL; 617 char flag = TTY_NORMAL;
618 u32 len = urb->actual_length;
619 int i;
651 char *ch; 620 char *ch;
652 621
653 dbg("%s - port %d", __func__, port->number); 622 dbg("%s - port %d", __func__, port->number);
@@ -685,12 +654,8 @@ static int ssu100_process_packet(struct tty_struct *tty,
685static void ssu100_process_read_urb(struct urb *urb) 654static void ssu100_process_read_urb(struct urb *urb)
686{ 655{
687 struct usb_serial_port *port = urb->context; 656 struct usb_serial_port *port = urb->context;
688 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
689 char *data = (char *)urb->transfer_buffer;
690 struct tty_struct *tty; 657 struct tty_struct *tty;
691 int count = 0; 658 int count;
692 int i;
693 int len;
694 659
695 dbg("%s", __func__); 660 dbg("%s", __func__);
696 661
@@ -698,10 +663,7 @@ static void ssu100_process_read_urb(struct urb *urb)
698 if (!tty) 663 if (!tty)
699 return; 664 return;
700 665
701 for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { 666 count = ssu100_process_packet(urb, tty);
702 len = min_t(int, urb->actual_length - i, priv->max_packet_size);
703 count += ssu100_process_packet(tty, port, priv, &data[i], len);
704 }
705 667
706 if (count) 668 if (count)
707 tty_flip_buffer_push(tty); 669 tty_flip_buffer_push(tty);
@@ -717,8 +679,6 @@ static struct usb_serial_driver ssu100_device = {
717 .id_table = id_table, 679 .id_table = id_table,
718 .usb_driver = &ssu100_driver, 680 .usb_driver = &ssu100_driver,
719 .num_ports = 1, 681 .num_ports = 1,
720 .bulk_in_size = 256,
721 .bulk_out_size = 256,
722 .open = ssu100_open, 682 .open = ssu100_open,
723 .close = ssu100_close, 683 .close = ssu100_close,
724 .attach = ssu100_attach, 684 .attach = ssu100_attach,
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h
index 2be298a1305b..3ab77c5d9819 100644
--- a/drivers/usb/serial/usb-wwan.h
+++ b/drivers/usb/serial/usb-wwan.h
@@ -18,6 +18,8 @@ extern void usb_wwan_set_termios(struct tty_struct *tty,
18extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file); 18extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file);
19extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, 19extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file,
20 unsigned int set, unsigned int clear); 20 unsigned int set, unsigned int clear);
21extern int usb_wwan_ioctl(struct tty_struct *tty, struct file *file,
22 unsigned int cmd, unsigned long arg);
21extern int usb_wwan_send_setup(struct usb_serial_port *port); 23extern int usb_wwan_send_setup(struct usb_serial_port *port);
22extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, 24extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
23 const unsigned char *buf, int count); 25 const unsigned char *buf, int count);
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index fbc946797801..b004b2a485c3 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -31,8 +31,10 @@
31#include <linux/tty_flip.h> 31#include <linux/tty_flip.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/bitops.h> 33#include <linux/bitops.h>
34#include <linux/uaccess.h>
34#include <linux/usb.h> 35#include <linux/usb.h>
35#include <linux/usb/serial.h> 36#include <linux/usb/serial.h>
37#include <linux/serial.h>
36#include "usb-wwan.h" 38#include "usb-wwan.h"
37 39
38static int debug; 40static int debug;
@@ -123,6 +125,83 @@ int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file,
123} 125}
124EXPORT_SYMBOL(usb_wwan_tiocmset); 126EXPORT_SYMBOL(usb_wwan_tiocmset);
125 127
128static int get_serial_info(struct usb_serial_port *port,
129 struct serial_struct __user *retinfo)
130{
131 struct serial_struct tmp;
132
133 if (!retinfo)
134 return -EFAULT;
135
136 memset(&tmp, 0, sizeof(tmp));
137 tmp.line = port->serial->minor;
138 tmp.port = port->number;
139 tmp.baud_base = tty_get_baud_rate(port->port.tty);
140 tmp.close_delay = port->port.close_delay / 10;
141 tmp.closing_wait = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
142 ASYNC_CLOSING_WAIT_NONE :
143 port->port.closing_wait / 10;
144
145 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
146 return -EFAULT;
147 return 0;
148}
149
150static int set_serial_info(struct usb_serial_port *port,
151 struct serial_struct __user *newinfo)
152{
153 struct serial_struct new_serial;
154 unsigned int closing_wait, close_delay;
155 int retval = 0;
156
157 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
158 return -EFAULT;
159
160 close_delay = new_serial.close_delay * 10;
161 closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
162 ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
163
164 mutex_lock(&port->port.mutex);
165
166 if (!capable(CAP_SYS_ADMIN)) {
167 if ((close_delay != port->port.close_delay) ||
168 (closing_wait != port->port.closing_wait))
169 retval = -EPERM;
170 else
171 retval = -EOPNOTSUPP;
172 } else {
173 port->port.close_delay = close_delay;
174 port->port.closing_wait = closing_wait;
175 }
176
177 mutex_unlock(&port->port.mutex);
178 return retval;
179}
180
181int usb_wwan_ioctl(struct tty_struct *tty, struct file *file,
182 unsigned int cmd, unsigned long arg)
183{
184 struct usb_serial_port *port = tty->driver_data;
185
186 dbg("%s cmd 0x%04x", __func__, cmd);
187
188 switch (cmd) {
189 case TIOCGSERIAL:
190 return get_serial_info(port,
191 (struct serial_struct __user *) arg);
192 case TIOCSSERIAL:
193 return set_serial_info(port,
194 (struct serial_struct __user *) arg);
195 default:
196 break;
197 }
198
199 dbg("%s arg not supported", __func__);
200
201 return -ENOIOCTLCMD;
202}
203EXPORT_SYMBOL(usb_wwan_ioctl);
204
126/* Write */ 205/* Write */
127int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, 206int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
128 const unsigned char *buf, int count) 207 const unsigned char *buf, int count)