diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-16 13:05:06 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-16 13:05:06 -0500 |
commit | 36facadd9ea98f8415d0dbb63e0763b7ee9d3911 (patch) | |
tree | 99dea00b332ed852f2b0a4923b581dd723f03634 /drivers/usb/serial | |
parent | 2faa83e2a519abea1055d156ce1b42b8fa57e87b (diff) | |
parent | 0b83ae960cd7d4a5ee02786ecf41ab45688999bf (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.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/ssu100.c | 56 | ||||
-rw-r--r-- | drivers/usb/serial/usb-wwan.h | 2 | ||||
-rw-r--r-- | drivers/usb/serial/usb_wwan.c | 79 |
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 | ||
467 | static 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 | |||
497 | static int ssu100_attach(struct usb_serial *serial) | 466 | static 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 | ||
644 | static int ssu100_process_packet(struct tty_struct *tty, | 612 | static 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, | |||
685 | static void ssu100_process_read_urb(struct urb *urb) | 654 | static 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, | |||
18 | extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file); | 18 | extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file); |
19 | extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, | 19 | extern 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); |
21 | extern int usb_wwan_ioctl(struct tty_struct *tty, struct file *file, | ||
22 | unsigned int cmd, unsigned long arg); | ||
21 | extern int usb_wwan_send_setup(struct usb_serial_port *port); | 23 | extern int usb_wwan_send_setup(struct usb_serial_port *port); |
22 | extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, | 24 | extern 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 | ||
38 | static int debug; | 40 | static int debug; |
@@ -123,6 +125,83 @@ int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, | |||
123 | } | 125 | } |
124 | EXPORT_SYMBOL(usb_wwan_tiocmset); | 126 | EXPORT_SYMBOL(usb_wwan_tiocmset); |
125 | 127 | ||
128 | static 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 | |||
150 | static 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 | |||
181 | int 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 | } | ||
203 | EXPORT_SYMBOL(usb_wwan_ioctl); | ||
204 | |||
126 | /* Write */ | 205 | /* Write */ |
127 | int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, | 206 | int 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) |