diff options
author | VomLehn <dvomlehn@cisco.com> | 2009-03-12 17:37:42 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-24 19:20:45 -0400 |
commit | d2ad67b3fa61eed52b22491210c668a94c7bf17e (patch) | |
tree | 1ecd2be5cc7add814fda5500683691b1d3af7e51 /drivers/usb/serial | |
parent | d23bac9f8b3cf1ad674d6390364d559103013213 (diff) |
USB: Fix cp2101 USB serial device driver termios functions for console use
This is really a follow up to the modifications Alan Cox made for commit
95da310e66ee8090119596c70ca8432e57f9a97f to pass a tty_struct to various
interface functions, which broke the serial configuration (termios) functions
when the device is being used as a console. These changes restore the
configuration to proper functioning both as a tty and as a console. As Alan
notes in that commit, these changes will need to be tweaked when we have
a proper console abstraction.
Signed-off-by: David VomLehn <dvomlehn@cisco.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/cp210x.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 292f0163b92c..e8d5133ce9c8 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -38,17 +38,21 @@ static int cp2101_open(struct tty_struct *, struct usb_serial_port *, | |||
38 | static void cp2101_cleanup(struct usb_serial_port *); | 38 | static void cp2101_cleanup(struct usb_serial_port *); |
39 | static void cp2101_close(struct tty_struct *, struct usb_serial_port *, | 39 | static void cp2101_close(struct tty_struct *, struct usb_serial_port *, |
40 | struct file*); | 40 | struct file*); |
41 | static void cp2101_get_termios(struct tty_struct *); | 41 | static void cp2101_get_termios(struct tty_struct *, |
42 | struct usb_serial_port *port); | ||
43 | static void cp2101_get_termios_port(struct usb_serial_port *port, | ||
44 | unsigned int *cflagp, unsigned int *baudp); | ||
42 | static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *, | 45 | static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *, |
43 | struct ktermios*); | 46 | struct ktermios*); |
44 | static int cp2101_tiocmget(struct tty_struct *, struct file *); | 47 | static int cp2101_tiocmget(struct tty_struct *, struct file *); |
45 | static int cp2101_tiocmset(struct tty_struct *, struct file *, | 48 | static int cp2101_tiocmset(struct tty_struct *, struct file *, |
46 | unsigned int, unsigned int); | 49 | unsigned int, unsigned int); |
50 | static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *, | ||
51 | unsigned int, unsigned int); | ||
47 | static void cp2101_break_ctl(struct tty_struct *, int); | 52 | static void cp2101_break_ctl(struct tty_struct *, int); |
48 | static int cp2101_startup(struct usb_serial *); | 53 | static int cp2101_startup(struct usb_serial *); |
49 | static void cp2101_shutdown(struct usb_serial *); | 54 | static void cp2101_shutdown(struct usb_serial *); |
50 | 55 | ||
51 | |||
52 | static int debug; | 56 | static int debug; |
53 | 57 | ||
54 | static struct usb_device_id id_table [] = { | 58 | static struct usb_device_id id_table [] = { |
@@ -369,10 +373,12 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
369 | } | 373 | } |
370 | 374 | ||
371 | /* Configure the termios structure */ | 375 | /* Configure the termios structure */ |
372 | cp2101_get_termios(tty); | 376 | cp2101_get_termios(tty, port); |
373 | 377 | ||
374 | /* Set the DTR and RTS pins low */ | 378 | /* Set the DTR and RTS pins low */ |
375 | cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0); | 379 | cp2101_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data |
380 | : port, | ||
381 | NULL, TIOCM_DTR | TIOCM_RTS, 0); | ||
376 | 382 | ||
377 | return 0; | 383 | return 0; |
378 | } | 384 | } |
@@ -414,9 +420,31 @@ static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
414 | * from the device, corrects any unsupported values, and configures the | 420 | * from the device, corrects any unsupported values, and configures the |
415 | * termios structure to reflect the state of the device | 421 | * termios structure to reflect the state of the device |
416 | */ | 422 | */ |
417 | static void cp2101_get_termios (struct tty_struct *tty) | 423 | static void cp2101_get_termios(struct tty_struct *tty, |
424 | struct usb_serial_port *port) | ||
425 | { | ||
426 | unsigned int baud; | ||
427 | |||
428 | if (tty) { | ||
429 | cp2101_get_termios_port(tty->driver_data, | ||
430 | &tty->termios->c_cflag, &baud); | ||
431 | tty_encode_baud_rate(tty, baud, baud); | ||
432 | } | ||
433 | |||
434 | else { | ||
435 | unsigned int cflag; | ||
436 | cflag = 0; | ||
437 | cp2101_get_termios_port(port, &cflag, &baud); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * cp2101_get_termios_port | ||
443 | * This is the heart of cp2101_get_termios which always uses a &usb_serial_port. | ||
444 | */ | ||
445 | static void cp2101_get_termios_port(struct usb_serial_port *port, | ||
446 | unsigned int *cflagp, unsigned int *baudp) | ||
418 | { | 447 | { |
419 | struct usb_serial_port *port = tty->driver_data; | ||
420 | unsigned int cflag, modem_ctl[4]; | 448 | unsigned int cflag, modem_ctl[4]; |
421 | unsigned int baud; | 449 | unsigned int baud; |
422 | unsigned int bits; | 450 | unsigned int bits; |
@@ -429,9 +457,9 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
429 | baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); | 457 | baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); |
430 | 458 | ||
431 | dbg("%s - baud rate = %d", __func__, baud); | 459 | dbg("%s - baud rate = %d", __func__, baud); |
460 | *baudp = baud; | ||
432 | 461 | ||
433 | tty_encode_baud_rate(tty, baud, baud); | 462 | cflag = *cflagp; |
434 | cflag = tty->termios->c_cflag; | ||
435 | 463 | ||
436 | cp2101_get_config(port, CP2101_BITS, &bits, 2); | 464 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
437 | cflag &= ~CSIZE; | 465 | cflag &= ~CSIZE; |
@@ -537,7 +565,7 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
537 | cflag &= ~CRTSCTS; | 565 | cflag &= ~CRTSCTS; |
538 | } | 566 | } |
539 | 567 | ||
540 | tty->termios->c_cflag = cflag; | 568 | *cflagp = cflag; |
541 | } | 569 | } |
542 | 570 | ||
543 | static void cp2101_set_termios(struct tty_struct *tty, | 571 | static void cp2101_set_termios(struct tty_struct *tty, |
@@ -669,6 +697,12 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | |||
669 | unsigned int set, unsigned int clear) | 697 | unsigned int set, unsigned int clear) |
670 | { | 698 | { |
671 | struct usb_serial_port *port = tty->driver_data; | 699 | struct usb_serial_port *port = tty->driver_data; |
700 | return cp2101_tiocmset_port(port, file, set, clear); | ||
701 | } | ||
702 | |||
703 | static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *file, | ||
704 | unsigned int set, unsigned int clear) | ||
705 | { | ||
672 | unsigned int control = 0; | 706 | unsigned int control = 0; |
673 | 707 | ||
674 | dbg("%s - port %d", __func__, port->number); | 708 | dbg("%s - port %d", __func__, port->number); |
@@ -693,7 +727,6 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | |||
693 | dbg("%s - control = 0x%.4x", __func__, control); | 727 | dbg("%s - control = 0x%.4x", __func__, control); |
694 | 728 | ||
695 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); | 729 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); |
696 | |||
697 | } | 730 | } |
698 | 731 | ||
699 | static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) | 732 | static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) |