diff options
author | Alan Cox <alan@redhat.com> | 2008-07-22 06:09:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-22 16:03:22 -0400 |
commit | 95da310e66ee8090119596c70ca8432e57f9a97f (patch) | |
tree | 7f18c30e9c9ad4d7d53df6453fa338be06f09a85 /drivers/usb/serial/belkin_sa.c | |
parent | 1aa3692da57c773e5c76de55c5c4a953962d360e (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/belkin_sa.c')
-rw-r--r-- | drivers/usb/serial/belkin_sa.c | 69 |
1 files changed, 25 insertions, 44 deletions
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 0a322fc53d6e..1a762692c739 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -89,14 +89,13 @@ static int debug; | |||
89 | /* function prototypes for a Belkin USB Serial Adapter F5U103 */ | 89 | /* function prototypes for a Belkin USB Serial Adapter F5U103 */ |
90 | static int belkin_sa_startup (struct usb_serial *serial); | 90 | static int belkin_sa_startup (struct usb_serial *serial); |
91 | static void belkin_sa_shutdown (struct usb_serial *serial); | 91 | static void belkin_sa_shutdown (struct usb_serial *serial); |
92 | static int belkin_sa_open (struct usb_serial_port *port, struct file *filp); | 92 | static int belkin_sa_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp); |
93 | static void belkin_sa_close (struct usb_serial_port *port, struct file *filp); | 93 | static void belkin_sa_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp); |
94 | static void belkin_sa_read_int_callback (struct urb *urb); | 94 | static void belkin_sa_read_int_callback (struct urb *urb); |
95 | static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios * old); | 95 | static void belkin_sa_set_termios (struct tty_struct *tty, struct usb_serial_port *port, struct ktermios * old); |
96 | static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 96 | static void belkin_sa_break_ctl (struct tty_struct *tty, int break_state ); |
97 | static void belkin_sa_break_ctl (struct usb_serial_port *port, int break_state ); | 97 | static int belkin_sa_tiocmget (struct tty_struct *tty, struct file *file); |
98 | static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file); | 98 | static int belkin_sa_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); |
99 | static int belkin_sa_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); | ||
100 | 99 | ||
101 | 100 | ||
102 | static struct usb_device_id id_table_combined [] = { | 101 | static struct usb_device_id id_table_combined [] = { |
@@ -132,7 +131,6 @@ static struct usb_serial_driver belkin_device = { | |||
132 | .open = belkin_sa_open, | 131 | .open = belkin_sa_open, |
133 | .close = belkin_sa_close, | 132 | .close = belkin_sa_close, |
134 | .read_int_callback = belkin_sa_read_int_callback, /* How we get the status info */ | 133 | .read_int_callback = belkin_sa_read_int_callback, /* How we get the status info */ |
135 | .ioctl = belkin_sa_ioctl, | ||
136 | .set_termios = belkin_sa_set_termios, | 134 | .set_termios = belkin_sa_set_termios, |
137 | .break_ctl = belkin_sa_break_ctl, | 135 | .break_ctl = belkin_sa_break_ctl, |
138 | .tiocmget = belkin_sa_tiocmget, | 136 | .tiocmget = belkin_sa_tiocmget, |
@@ -190,7 +188,7 @@ static int belkin_sa_startup (struct usb_serial *serial) | |||
190 | } | 188 | } |
191 | 189 | ||
192 | 190 | ||
193 | static void belkin_sa_shutdown (struct usb_serial *serial) | 191 | static void belkin_sa_shutdown(struct usb_serial *serial) |
194 | { | 192 | { |
195 | struct belkin_sa_private *priv; | 193 | struct belkin_sa_private *priv; |
196 | int i; | 194 | int i; |
@@ -206,7 +204,7 @@ static void belkin_sa_shutdown (struct usb_serial *serial) | |||
206 | } | 204 | } |
207 | 205 | ||
208 | 206 | ||
209 | static int belkin_sa_open (struct usb_serial_port *port, struct file *filp) | 207 | static int belkin_sa_open(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp) |
210 | { | 208 | { |
211 | int retval = 0; | 209 | int retval = 0; |
212 | 210 | ||
@@ -235,7 +233,8 @@ exit: | |||
235 | } /* belkin_sa_open */ | 233 | } /* belkin_sa_open */ |
236 | 234 | ||
237 | 235 | ||
238 | static void belkin_sa_close (struct usb_serial_port *port, struct file *filp) | 236 | static void belkin_sa_close (struct tty_struct *tty, |
237 | struct usb_serial_port *port, struct file *filp) | ||
239 | { | 238 | { |
240 | dbg("%s port %d", __func__, port->number); | 239 | dbg("%s port %d", __func__, port->number); |
241 | 240 | ||
@@ -246,7 +245,7 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp) | |||
246 | } /* belkin_sa_close */ | 245 | } /* belkin_sa_close */ |
247 | 246 | ||
248 | 247 | ||
249 | static void belkin_sa_read_int_callback (struct urb *urb) | 248 | static void belkin_sa_read_int_callback(struct urb *urb) |
250 | { | 249 | { |
251 | struct usb_serial_port *port = urb->context; | 250 | struct usb_serial_port *port = urb->context; |
252 | struct belkin_sa_private *priv; | 251 | struct belkin_sa_private *priv; |
@@ -311,7 +310,7 @@ static void belkin_sa_read_int_callback (struct urb *urb) | |||
311 | * to look in to this before committing any code. | 310 | * to look in to this before committing any code. |
312 | */ | 311 | */ |
313 | if (priv->last_lsr & BELKIN_SA_LSR_ERR) { | 312 | if (priv->last_lsr & BELKIN_SA_LSR_ERR) { |
314 | tty = port->tty; | 313 | tty = port->port.tty; |
315 | /* Overrun Error */ | 314 | /* Overrun Error */ |
316 | if (priv->last_lsr & BELKIN_SA_LSR_OE) { | 315 | if (priv->last_lsr & BELKIN_SA_LSR_OE) { |
317 | } | 316 | } |
@@ -334,7 +333,8 @@ exit: | |||
334 | __func__, retval); | 333 | __func__, retval); |
335 | } | 334 | } |
336 | 335 | ||
337 | static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) | 336 | static void belkin_sa_set_termios(struct tty_struct *tty, |
337 | struct usb_serial_port *port, struct ktermios *old_termios) | ||
338 | { | 338 | { |
339 | struct usb_serial *serial = port->serial; | 339 | struct usb_serial *serial = port->serial; |
340 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); | 340 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); |
@@ -347,7 +347,7 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios | |||
347 | unsigned long control_state; | 347 | unsigned long control_state; |
348 | int bad_flow_control; | 348 | int bad_flow_control; |
349 | speed_t baud; | 349 | speed_t baud; |
350 | struct ktermios *termios = port->tty->termios; | 350 | struct ktermios *termios = tty->termios; |
351 | 351 | ||
352 | iflag = termios->c_iflag; | 352 | iflag = termios->c_iflag; |
353 | cflag = termios->c_cflag; | 353 | cflag = termios->c_cflag; |
@@ -377,7 +377,7 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios | |||
377 | } | 377 | } |
378 | } | 378 | } |
379 | 379 | ||
380 | baud = tty_get_baud_rate(port->tty); | 380 | baud = tty_get_baud_rate(tty); |
381 | if (baud) { | 381 | if (baud) { |
382 | urb_value = BELKIN_SA_BAUD(baud); | 382 | urb_value = BELKIN_SA_BAUD(baud); |
383 | /* Clip to maximum speed */ | 383 | /* Clip to maximum speed */ |
@@ -387,7 +387,7 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios | |||
387 | baud = BELKIN_SA_BAUD(urb_value); | 387 | baud = BELKIN_SA_BAUD(urb_value); |
388 | 388 | ||
389 | /* Report the actual baud rate back to the caller */ | 389 | /* Report the actual baud rate back to the caller */ |
390 | tty_encode_baud_rate(port->tty, baud, baud); | 390 | tty_encode_baud_rate(tty, baud, baud); |
391 | if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) | 391 | if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) |
392 | err("Set baudrate error"); | 392 | err("Set baudrate error"); |
393 | } else { | 393 | } else { |
@@ -463,8 +463,9 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios | |||
463 | } /* belkin_sa_set_termios */ | 463 | } /* belkin_sa_set_termios */ |
464 | 464 | ||
465 | 465 | ||
466 | static void belkin_sa_break_ctl( struct usb_serial_port *port, int break_state ) | 466 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) |
467 | { | 467 | { |
468 | struct usb_serial_port *port = tty->driver_data; | ||
468 | struct usb_serial *serial = port->serial; | 469 | struct usb_serial *serial = port->serial; |
469 | 470 | ||
470 | if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0) | 471 | if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0) |
@@ -472,8 +473,9 @@ static void belkin_sa_break_ctl( struct usb_serial_port *port, int break_state ) | |||
472 | } | 473 | } |
473 | 474 | ||
474 | 475 | ||
475 | static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file) | 476 | static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file) |
476 | { | 477 | { |
478 | struct usb_serial_port *port = tty->driver_data; | ||
477 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); | 479 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); |
478 | unsigned long control_state; | 480 | unsigned long control_state; |
479 | unsigned long flags; | 481 | unsigned long flags; |
@@ -488,9 +490,10 @@ static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file) | |||
488 | } | 490 | } |
489 | 491 | ||
490 | 492 | ||
491 | static int belkin_sa_tiocmset (struct usb_serial_port *port, struct file *file, | 493 | static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, |
492 | unsigned int set, unsigned int clear) | 494 | unsigned int set, unsigned int clear) |
493 | { | 495 | { |
496 | struct usb_serial_port *port = tty->driver_data; | ||
494 | struct usb_serial *serial = port->serial; | 497 | struct usb_serial *serial = port->serial; |
495 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); | 498 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); |
496 | unsigned long control_state; | 499 | unsigned long control_state; |
@@ -540,29 +543,7 @@ exit: | |||
540 | } | 543 | } |
541 | 544 | ||
542 | 545 | ||
543 | static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) | 546 | static int __init belkin_sa_init(void) |
544 | { | ||
545 | switch (cmd) { | ||
546 | case TIOCMIWAIT: | ||
547 | /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ | ||
548 | /* TODO */ | ||
549 | return( 0 ); | ||
550 | |||
551 | case TIOCGICOUNT: | ||
552 | /* return count of modemline transitions */ | ||
553 | /* TODO */ | ||
554 | return 0; | ||
555 | |||
556 | default: | ||
557 | dbg("belkin_sa_ioctl arg not supported - 0x%04x",cmd); | ||
558 | return(-ENOIOCTLCMD); | ||
559 | break; | ||
560 | } | ||
561 | return 0; | ||
562 | } /* belkin_sa_ioctl */ | ||
563 | |||
564 | |||
565 | static int __init belkin_sa_init (void) | ||
566 | { | 547 | { |
567 | int retval; | 548 | int retval; |
568 | retval = usb_serial_register(&belkin_device); | 549 | retval = usb_serial_register(&belkin_device); |
@@ -583,7 +564,7 @@ failed_usb_serial_register: | |||
583 | static void __exit belkin_sa_exit (void) | 564 | static void __exit belkin_sa_exit (void) |
584 | { | 565 | { |
585 | usb_deregister (&belkin_driver); | 566 | usb_deregister (&belkin_driver); |
586 | usb_serial_deregister (&belkin_device); | 567 | usb_serial_deregister(&belkin_device); |
587 | } | 568 | } |
588 | 569 | ||
589 | 570 | ||