aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/option.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-07-22 06:09:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:03:22 -0400
commit95da310e66ee8090119596c70ca8432e57f9a97f (patch)
tree7f18c30e9c9ad4d7d53df6453fa338be06f09a85 /drivers/usb/serial/option.c
parent1aa3692da57c773e5c76de55c5c4a953962d360e (diff)
usb_serial: API all change
USB serial likes to use port->tty back pointers for the real work it does and to do so without any actual locking. Unfortunately when you consider hangup events, hangup/parallel reopen or even worse hangup followed by parallel close events the tty->port and port->tty pointers are not guaranteed to be the same as port->tty is the active tty while tty->port is the port the tty may or may not still be attached to. So rework the entire API to pass the tty struct. For console cases we need to pass both for now. This shows up multiple drivers that immediately crash with USB console some of which have been fixed in the process. Longer term we need a proper tty as console abstraction Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r--drivers/usb/serial/option.c105
1 files changed, 40 insertions, 65 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 1e936a1cbe0b..4350990abf14 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -43,29 +43,23 @@
43#include <linux/usb/serial.h> 43#include <linux/usb/serial.h>
44 44
45/* Function prototypes */ 45/* Function prototypes */
46static int option_open(struct usb_serial_port *port, struct file *filp); 46static int option_open(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
47static void option_close(struct usb_serial_port *port, struct file *filp); 47static void option_close(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
48static int option_startup(struct usb_serial *serial); 48static int option_startup(struct usb_serial *serial);
49static void option_shutdown(struct usb_serial *serial); 49static void option_shutdown(struct usb_serial *serial);
50static void option_rx_throttle(struct usb_serial_port *port); 50static int option_write_room(struct tty_struct *tty);
51static void option_rx_unthrottle(struct usb_serial_port *port);
52static int option_write_room(struct usb_serial_port *port);
53 51
54static void option_instat_callback(struct urb *urb); 52static void option_instat_callback(struct urb *urb);
55 53
56static int option_write(struct usb_serial_port *port, 54static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
57 const unsigned char *buf, int count); 55 const unsigned char *buf, int count);
58 56static int option_chars_in_buffer(struct tty_struct *tty);
59static int option_chars_in_buffer(struct usb_serial_port *port); 57static void option_set_termios(struct tty_struct *tty,
60static int option_ioctl(struct usb_serial_port *port, struct file *file, 58 struct usb_serial_port *port, struct ktermios *old);
61 unsigned int cmd, unsigned long arg); 59static int option_tiocmget(struct tty_struct *tty, struct file *file);
62static void option_set_termios(struct usb_serial_port *port, 60static int option_tiocmset(struct tty_struct *tty, struct file *file,
63 struct ktermios *old);
64static void option_break_ctl(struct usb_serial_port *port, int break_state);
65static int option_tiocmget(struct usb_serial_port *port, struct file *file);
66static int option_tiocmset(struct usb_serial_port *port, struct file *file,
67 unsigned int set, unsigned int clear); 61 unsigned int set, unsigned int clear);
68static int option_send_setup(struct usb_serial_port *port); 62static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port);
69 63
70/* Vendor and product IDs */ 64/* Vendor and product IDs */
71#define OPTION_VENDOR_ID 0x0AF0 65#define OPTION_VENDOR_ID 0x0AF0
@@ -342,11 +336,7 @@ static struct usb_serial_driver option_1port_device = {
342 .write = option_write, 336 .write = option_write,
343 .write_room = option_write_room, 337 .write_room = option_write_room,
344 .chars_in_buffer = option_chars_in_buffer, 338 .chars_in_buffer = option_chars_in_buffer,
345 .throttle = option_rx_throttle,
346 .unthrottle = option_rx_unthrottle,
347 .ioctl = option_ioctl,
348 .set_termios = option_set_termios, 339 .set_termios = option_set_termios,
349 .break_ctl = option_break_ctl,
350 .tiocmget = option_tiocmget, 340 .tiocmget = option_tiocmget,
351 .tiocmset = option_tiocmset, 341 .tiocmset = option_tiocmset,
352 .attach = option_startup, 342 .attach = option_startup,
@@ -417,33 +407,18 @@ static void __exit option_exit(void)
417module_init(option_init); 407module_init(option_init);
418module_exit(option_exit); 408module_exit(option_exit);
419 409
420static void option_rx_throttle(struct usb_serial_port *port) 410static void option_set_termios(struct tty_struct *tty,
421{ 411 struct usb_serial_port *port, struct ktermios *old_termios)
422 dbg("%s", __func__);
423}
424
425static void option_rx_unthrottle(struct usb_serial_port *port)
426{
427 dbg("%s", __func__);
428}
429
430static void option_break_ctl(struct usb_serial_port *port, int break_state)
431{
432 /* Unfortunately, I don't know how to send a break */
433 dbg("%s", __func__);
434}
435
436static void option_set_termios(struct usb_serial_port *port,
437 struct ktermios *old_termios)
438{ 412{
439 dbg("%s", __func__); 413 dbg("%s", __func__);
440 /* Doesn't support option setting */ 414 /* Doesn't support option setting */
441 tty_termios_copy_hw(port->tty->termios, old_termios); 415 tty_termios_copy_hw(tty->termios, old_termios);
442 option_send_setup(port); 416 option_send_setup(tty, port);
443} 417}
444 418
445static int option_tiocmget(struct usb_serial_port *port, struct file *file) 419static int option_tiocmget(struct tty_struct *tty, struct file *file)
446{ 420{
421 struct usb_serial_port *port = tty->driver_data;
447 unsigned int value; 422 unsigned int value;
448 struct option_port_private *portdata; 423 struct option_port_private *portdata;
449 424
@@ -459,9 +434,10 @@ static int option_tiocmget(struct usb_serial_port *port, struct file *file)
459 return value; 434 return value;
460} 435}
461 436
462static int option_tiocmset(struct usb_serial_port *port, struct file *file, 437static int option_tiocmset(struct tty_struct *tty, struct file *file,
463 unsigned int set, unsigned int clear) 438 unsigned int set, unsigned int clear)
464{ 439{
440 struct usb_serial_port *port = tty->driver_data;
465 struct option_port_private *portdata; 441 struct option_port_private *portdata;
466 442
467 portdata = usb_get_serial_port_data(port); 443 portdata = usb_get_serial_port_data(port);
@@ -476,17 +452,11 @@ static int option_tiocmset(struct usb_serial_port *port, struct file *file,
476 portdata->rts_state = 0; 452 portdata->rts_state = 0;
477 if (clear & TIOCM_DTR) 453 if (clear & TIOCM_DTR)
478 portdata->dtr_state = 0; 454 portdata->dtr_state = 0;
479 return option_send_setup(port); 455 return option_send_setup(tty, port);
480}
481
482static int option_ioctl(struct usb_serial_port *port, struct file *file,
483 unsigned int cmd, unsigned long arg)
484{
485 return -ENOIOCTLCMD;
486} 456}
487 457
488/* Write */ 458/* Write */
489static int option_write(struct usb_serial_port *port, 459static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
490 const unsigned char *buf, int count) 460 const unsigned char *buf, int count)
491{ 461{
492 struct option_port_private *portdata; 462 struct option_port_private *portdata;
@@ -562,7 +532,7 @@ static void option_indat_callback(struct urb *urb)
562 dbg("%s: nonzero status: %d on endpoint %02x.", 532 dbg("%s: nonzero status: %d on endpoint %02x.",
563 __func__, status, endpoint); 533 __func__, status, endpoint);
564 } else { 534 } else {
565 tty = port->tty; 535 tty = port->port.tty;
566 if (urb->actual_length) { 536 if (urb->actual_length) {
567 tty_buffer_request_room(tty, urb->actual_length); 537 tty_buffer_request_room(tty, urb->actual_length);
568 tty_insert_flip_string(tty, data, urb->actual_length); 538 tty_insert_flip_string(tty, data, urb->actual_length);
@@ -572,7 +542,7 @@ static void option_indat_callback(struct urb *urb)
572 } 542 }
573 543
574 /* Resubmit urb so we continue receiving */ 544 /* Resubmit urb so we continue receiving */
575 if (port->open_count && status != -ESHUTDOWN) { 545 if (port->port.count && status != -ESHUTDOWN) {
576 err = usb_submit_urb(urb, GFP_ATOMIC); 546 err = usb_submit_urb(urb, GFP_ATOMIC);
577 if (err) 547 if (err)
578 printk(KERN_ERR "%s: resubmit read urb failed. " 548 printk(KERN_ERR "%s: resubmit read urb failed. "
@@ -638,9 +608,9 @@ static void option_instat_callback(struct urb *urb)
638 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 608 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
639 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 609 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
640 610
641 if (port->tty && !C_CLOCAL(port->tty) && 611 if (port->port.tty && !C_CLOCAL(port->port.tty) &&
642 old_dcd_state && !portdata->dcd_state) 612 old_dcd_state && !portdata->dcd_state)
643 tty_hangup(port->tty); 613 tty_hangup(port->port.tty);
644 } else { 614 } else {
645 dbg("%s: type %x req %x", __func__, 615 dbg("%s: type %x req %x", __func__,
646 req_pkt->bRequestType,req_pkt->bRequest); 616 req_pkt->bRequestType,req_pkt->bRequest);
@@ -658,8 +628,9 @@ static void option_instat_callback(struct urb *urb)
658 } 628 }
659} 629}
660 630
661static int option_write_room(struct usb_serial_port *port) 631static int option_write_room(struct tty_struct *tty)
662{ 632{
633 struct usb_serial_port *port = tty->driver_data;
663 struct option_port_private *portdata; 634 struct option_port_private *portdata;
664 int i; 635 int i;
665 int data_len = 0; 636 int data_len = 0;
@@ -678,8 +649,9 @@ static int option_write_room(struct usb_serial_port *port)
678 return data_len; 649 return data_len;
679} 650}
680 651
681static int option_chars_in_buffer(struct usb_serial_port *port) 652static int option_chars_in_buffer(struct tty_struct *tty)
682{ 653{
654 struct usb_serial_port *port = tty->driver_data;
683 struct option_port_private *portdata; 655 struct option_port_private *portdata;
684 int i; 656 int i;
685 int data_len = 0; 657 int data_len = 0;
@@ -698,7 +670,8 @@ static int option_chars_in_buffer(struct usb_serial_port *port)
698 return data_len; 670 return data_len;
699} 671}
700 672
701static int option_open(struct usb_serial_port *port, struct file *filp) 673static int option_open(struct tty_struct *tty,
674 struct usb_serial_port *port, struct file *filp)
702{ 675{
703 struct option_port_private *portdata; 676 struct option_port_private *portdata;
704 struct usb_serial *serial = port->serial; 677 struct usb_serial *serial = port->serial;
@@ -748,14 +721,16 @@ static int option_open(struct usb_serial_port *port, struct file *filp)
748 usb_pipeout(urb->pipe), 0); */ 721 usb_pipeout(urb->pipe), 0); */
749 } 722 }
750 723
751 port->tty->low_latency = 1; 724 if (tty)
725 tty->low_latency = 1;
752 726
753 option_send_setup(port); 727 option_send_setup(tty, port);
754 728
755 return (0); 729 return (0);
756} 730}
757 731
758static void option_close(struct usb_serial_port *port, struct file *filp) 732static void option_close(struct tty_struct *tty,
733 struct usb_serial_port *port, struct file *filp)
759{ 734{
760 int i; 735 int i;
761 struct usb_serial *serial = port->serial; 736 struct usb_serial *serial = port->serial;
@@ -770,7 +745,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp)
770 if (serial->dev) { 745 if (serial->dev) {
771 mutex_lock(&serial->disc_mutex); 746 mutex_lock(&serial->disc_mutex);
772 if (!serial->disconnected) 747 if (!serial->disconnected)
773 option_send_setup(port); 748 option_send_setup(tty, port);
774 mutex_unlock(&serial->disc_mutex); 749 mutex_unlock(&serial->disc_mutex);
775 750
776 /* Stop reading/writing urbs */ 751 /* Stop reading/writing urbs */
@@ -779,7 +754,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp)
779 for (i = 0; i < N_OUT_URB; i++) 754 for (i = 0; i < N_OUT_URB; i++)
780 usb_kill_urb(portdata->out_urbs[i]); 755 usb_kill_urb(portdata->out_urbs[i]);
781 } 756 }
782 port->tty = NULL; 757 port->port.tty = NULL; /* FIXME */
783} 758}
784 759
785/* Helper functions used by option_setup_urbs */ 760/* Helper functions used by option_setup_urbs */
@@ -841,7 +816,8 @@ static void option_setup_urbs(struct usb_serial *serial)
841 * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN 816 * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN
842 * CDC. 817 * CDC.
843*/ 818*/
844static int option_send_setup(struct usb_serial_port *port) 819static int option_send_setup(struct tty_struct *tty,
820 struct usb_serial_port *port)
845{ 821{
846 struct usb_serial *serial = port->serial; 822 struct usb_serial *serial = port->serial;
847 struct option_port_private *portdata; 823 struct option_port_private *portdata;
@@ -850,7 +826,7 @@ static int option_send_setup(struct usb_serial_port *port)
850 826
851 portdata = usb_get_serial_port_data(port); 827 portdata = usb_get_serial_port_data(port);
852 828
853 if (port->tty) { 829 if (tty) {
854 int val = 0; 830 int val = 0;
855 if (portdata->dtr_state) 831 if (portdata->dtr_state)
856 val |= 0x01; 832 val |= 0x01;
@@ -861,7 +837,6 @@ static int option_send_setup(struct usb_serial_port *port)
861 usb_rcvctrlpipe(serial->dev, 0), 837 usb_rcvctrlpipe(serial->dev, 0),
862 0x22,0x21,val,ifNum,NULL,0,USB_CTRL_SET_TIMEOUT); 838 0x22,0x21,val,ifNum,NULL,0,USB_CTRL_SET_TIMEOUT);
863 } 839 }
864
865 return 0; 840 return 0;
866} 841}
867 842