aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cp2101.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/cp2101.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/cp2101.c')
-rw-r--r--drivers/usb/serial/cp2101.c74
1 files changed, 38 insertions, 36 deletions
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 2bc5576c443a..46c33fc9f6ce 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -37,15 +37,18 @@
37/* 37/*
38 * Function Prototypes 38 * Function Prototypes
39 */ 39 */
40static int cp2101_open(struct usb_serial_port*, struct file*); 40static int cp2101_open(struct tty_struct *, struct usb_serial_port *,
41static void cp2101_cleanup(struct usb_serial_port*); 41 struct file *);
42static void cp2101_close(struct usb_serial_port*, struct file*); 42static void cp2101_cleanup(struct usb_serial_port *);
43static void cp2101_get_termios(struct usb_serial_port*); 43static void cp2101_close(struct tty_struct *, struct usb_serial_port *,
44static void cp2101_set_termios(struct usb_serial_port*, struct ktermios*); 44 struct file*);
45static int cp2101_tiocmget (struct usb_serial_port *, struct file *); 45static void cp2101_get_termios(struct tty_struct *);
46static int cp2101_tiocmset (struct usb_serial_port *, struct file *, 46static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *,
47 struct ktermios*);
48static int cp2101_tiocmget (struct tty_struct *, struct file *);
49static int cp2101_tiocmset (struct tty_struct *, struct file *,
47 unsigned int, unsigned int); 50 unsigned int, unsigned int);
48static void cp2101_break_ctl(struct usb_serial_port*, int); 51static void cp2101_break_ctl(struct tty_struct *, int);
49static int cp2101_startup (struct usb_serial *); 52static int cp2101_startup (struct usb_serial *);
50static void cp2101_shutdown(struct usb_serial*); 53static void cp2101_shutdown(struct usb_serial*);
51 54
@@ -182,7 +185,7 @@ static struct usb_serial_driver cp2101_device = {
182 * 'data' is a pointer to a pre-allocated array of integers large 185 * 'data' is a pointer to a pre-allocated array of integers large
183 * enough to hold 'size' bytes (with 4 bytes to each integer) 186 * enough to hold 'size' bytes (with 4 bytes to each integer)
184 */ 187 */
185static int cp2101_get_config(struct usb_serial_port* port, u8 request, 188static int cp2101_get_config(struct usb_serial_port *port, u8 request,
186 unsigned int *data, int size) 189 unsigned int *data, int size)
187{ 190{
188 struct usb_serial *serial = port->serial; 191 struct usb_serial *serial = port->serial;
@@ -228,7 +231,7 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request,
228 * Values less than 16 bits wide are sent directly 231 * Values less than 16 bits wide are sent directly
229 * 'size' is specified in bytes. 232 * 'size' is specified in bytes.
230 */ 233 */
231static int cp2101_set_config(struct usb_serial_port* port, u8 request, 234static int cp2101_set_config(struct usb_serial_port *port, u8 request,
232 unsigned int *data, int size) 235 unsigned int *data, int size)
233{ 236{
234 struct usb_serial *serial = port->serial; 237 struct usb_serial *serial = port->serial;
@@ -283,13 +286,14 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request,
283 * Convenience function for calling cp2101_set_config on single data values 286 * Convenience function for calling cp2101_set_config on single data values
284 * without requiring an integer pointer 287 * without requiring an integer pointer
285 */ 288 */
286static inline int cp2101_set_config_single(struct usb_serial_port* port, 289static inline int cp2101_set_config_single(struct usb_serial_port *port,
287 u8 request, unsigned int data) 290 u8 request, unsigned int data)
288{ 291{
289 return cp2101_set_config(port, request, &data, 2); 292 return cp2101_set_config(port, request, &data, 2);
290} 293}
291 294
292static int cp2101_open (struct usb_serial_port *port, struct file *filp) 295static int cp2101_open (struct tty_struct *tty, struct usb_serial_port *port,
296 struct file *filp)
293{ 297{
294 struct usb_serial *serial = port->serial; 298 struct usb_serial *serial = port->serial;
295 int result; 299 int result;
@@ -318,10 +322,10 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
318 } 322 }
319 323
320 /* Configure the termios structure */ 324 /* Configure the termios structure */
321 cp2101_get_termios(port); 325 cp2101_get_termios(tty);
322 326
323 /* Set the DTR and RTS pins low */ 327 /* Set the DTR and RTS pins low */
324 cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0); 328 cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0);
325 329
326 return 0; 330 return 0;
327} 331}
@@ -341,7 +345,8 @@ static void cp2101_cleanup (struct usb_serial_port *port)
341 } 345 }
342} 346}
343 347
344static void cp2101_close (struct usb_serial_port *port, struct file * filp) 348static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
349 struct file * filp)
345{ 350{
346 dbg("%s - port %d", __func__, port->number); 351 dbg("%s - port %d", __func__, port->number);
347 352
@@ -362,19 +367,15 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp)
362 * from the device, corrects any unsupported values, and configures the 367 * from the device, corrects any unsupported values, and configures the
363 * termios structure to reflect the state of the device 368 * termios structure to reflect the state of the device
364 */ 369 */
365static void cp2101_get_termios (struct usb_serial_port *port) 370static void cp2101_get_termios (struct tty_struct *tty)
366{ 371{
372 struct usb_serial_port *port = tty->driver_data;
367 unsigned int cflag, modem_ctl[4]; 373 unsigned int cflag, modem_ctl[4];
368 unsigned int baud; 374 unsigned int baud;
369 unsigned int bits; 375 unsigned int bits;
370 376
371 dbg("%s - port %d", __func__, port->number); 377 dbg("%s - port %d", __func__, port->number);
372 378
373 if (!port->tty || !port->tty->termios) {
374 dbg("%s - no tty structures", __func__);
375 return;
376 }
377
378 cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); 379 cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
379 /* Convert to baudrate */ 380 /* Convert to baudrate */
380 if (baud) 381 if (baud)
@@ -382,8 +383,8 @@ static void cp2101_get_termios (struct usb_serial_port *port)
382 383
383 dbg("%s - baud rate = %d", __func__, baud); 384 dbg("%s - baud rate = %d", __func__, baud);
384 385
385 tty_encode_baud_rate(port->tty, baud, baud); 386 tty_encode_baud_rate(tty, baud, baud);
386 cflag = port->tty->termios->c_cflag; 387 cflag = tty->termios->c_cflag;
387 388
388 cp2101_get_config(port, CP2101_BITS, &bits, 2); 389 cp2101_get_config(port, CP2101_BITS, &bits, 2);
389 cflag &= ~CSIZE; 390 cflag &= ~CSIZE;
@@ -491,11 +492,11 @@ static void cp2101_get_termios (struct usb_serial_port *port)
491 cflag &= ~CRTSCTS; 492 cflag &= ~CRTSCTS;
492 } 493 }
493 494
494 port->tty->termios->c_cflag = cflag; 495 tty->termios->c_cflag = cflag;
495} 496}
496 497
497static void cp2101_set_termios (struct usb_serial_port *port, 498static void cp2101_set_termios (struct tty_struct *tty,
498 struct ktermios *old_termios) 499 struct usb_serial_port *port, struct ktermios *old_termios)
499{ 500{
500 unsigned int cflag, old_cflag; 501 unsigned int cflag, old_cflag;
501 unsigned int baud = 0, bits; 502 unsigned int baud = 0, bits;
@@ -503,15 +504,13 @@ static void cp2101_set_termios (struct usb_serial_port *port,
503 504
504 dbg("%s - port %d", __func__, port->number); 505 dbg("%s - port %d", __func__, port->number);
505 506
506 if (!port->tty || !port->tty->termios) { 507 if (!tty)
507 dbg("%s - no tty structures", __func__);
508 return; 508 return;
509 }
510 port->tty->termios->c_cflag &= ~CMSPAR;
511 509
512 cflag = port->tty->termios->c_cflag; 510 tty->termios->c_cflag &= ~CMSPAR;
511 cflag = tty->termios->c_cflag;
513 old_cflag = old_termios->c_cflag; 512 old_cflag = old_termios->c_cflag;
514 baud = tty_get_baud_rate(port->tty); 513 baud = tty_get_baud_rate(tty);
515 514
516 /* If the baud rate is to be updated*/ 515 /* If the baud rate is to be updated*/
517 if (baud != tty_termios_baud_rate(old_termios)) { 516 if (baud != tty_termios_baud_rate(old_termios)) {
@@ -554,7 +553,7 @@ static void cp2101_set_termios (struct usb_serial_port *port,
554 } 553 }
555 } 554 }
556 /* Report back the resulting baud rate */ 555 /* Report back the resulting baud rate */
557 tty_encode_baud_rate(port->tty, baud, baud); 556 tty_encode_baud_rate(tty, baud, baud);
558 557
559 /* If the number of data bits is to be updated */ 558 /* If the number of data bits is to be updated */
560 if ((cflag & CSIZE) != (old_cflag & CSIZE)) { 559 if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
@@ -651,9 +650,10 @@ static void cp2101_set_termios (struct usb_serial_port *port,
651 650
652} 651}
653 652
654static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, 653static int cp2101_tiocmset (struct tty_struct *tty, struct file *file,
655 unsigned int set, unsigned int clear) 654 unsigned int set, unsigned int clear)
656{ 655{
656 struct usb_serial_port *port = tty->driver_data;
657 unsigned int control = 0; 657 unsigned int control = 0;
658 658
659 dbg("%s - port %d", __func__, port->number); 659 dbg("%s - port %d", __func__, port->number);
@@ -681,8 +681,9 @@ static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file,
681 681
682} 682}
683 683
684static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) 684static int cp2101_tiocmget (struct tty_struct *tty, struct file *file)
685{ 685{
686 struct usb_serial_port *port = tty->driver_data;
686 unsigned int control; 687 unsigned int control;
687 int result; 688 int result;
688 689
@@ -702,8 +703,9 @@ static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file)
702 return result; 703 return result;
703} 704}
704 705
705static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) 706static void cp2101_break_ctl (struct tty_struct *tty, int break_state)
706{ 707{
708 struct usb_serial_port *port = tty->driver_data;
707 unsigned int state; 709 unsigned int state;
708 710
709 dbg("%s - port %d", __func__, port->number); 711 dbg("%s - port %d", __func__, port->number);