aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.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/sierra.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/sierra.c')
-rw-r--r--drivers/usb/serial/sierra.c93
1 files changed, 29 insertions, 64 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 29074c1ba22b..892020d48555 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -250,7 +250,8 @@ struct sierra_port_private {
250 int ri_state; 250 int ri_state;
251}; 251};
252 252
253static int sierra_send_setup(struct usb_serial_port *port) 253static int sierra_send_setup(struct tty_struct *tty,
254 struct usb_serial_port *port)
254{ 255{
255 struct usb_serial *serial = port->serial; 256 struct usb_serial *serial = port->serial;
256 struct sierra_port_private *portdata; 257 struct sierra_port_private *portdata;
@@ -260,7 +261,7 @@ static int sierra_send_setup(struct usb_serial_port *port)
260 261
261 portdata = usb_get_serial_port_data(port); 262 portdata = usb_get_serial_port_data(port);
262 263
263 if (port->tty) { 264 if (tty) {
264 int val = 0; 265 int val = 0;
265 if (portdata->dtr_state) 266 if (portdata->dtr_state)
266 val |= 0x01; 267 val |= 0x01;
@@ -284,32 +285,17 @@ static int sierra_send_setup(struct usb_serial_port *port)
284 return 0; 285 return 0;
285} 286}
286 287
287static void sierra_rx_throttle(struct usb_serial_port *port) 288static void sierra_set_termios(struct tty_struct *tty,
289 struct usb_serial_port *port, struct ktermios *old_termios)
288{ 290{
289 dbg("%s", __func__); 291 dbg("%s", __func__);
292 tty_termios_copy_hw(tty->termios, old_termios);
293 sierra_send_setup(tty, port);
290} 294}
291 295
292static void sierra_rx_unthrottle(struct usb_serial_port *port) 296static int sierra_tiocmget(struct tty_struct *tty, struct file *file)
293{
294 dbg("%s", __func__);
295}
296
297static void sierra_break_ctl(struct usb_serial_port *port, int break_state)
298{
299 /* Unfortunately, I don't know how to send a break */
300 dbg("%s", __func__);
301}
302
303static void sierra_set_termios(struct usb_serial_port *port,
304 struct ktermios *old_termios)
305{
306 dbg("%s", __func__);
307 tty_termios_copy_hw(port->tty->termios, old_termios);
308 sierra_send_setup(port);
309}
310
311static int sierra_tiocmget(struct usb_serial_port *port, struct file *file)
312{ 297{
298 struct usb_serial_port *port = tty->driver_data;
313 unsigned int value; 299 unsigned int value;
314 struct sierra_port_private *portdata; 300 struct sierra_port_private *portdata;
315 301
@@ -325,9 +311,10 @@ static int sierra_tiocmget(struct usb_serial_port *port, struct file *file)
325 return value; 311 return value;
326} 312}
327 313
328static int sierra_tiocmset(struct usb_serial_port *port, struct file *file, 314static int sierra_tiocmset(struct tty_struct *tty, struct file *file,
329 unsigned int set, unsigned int clear) 315 unsigned int set, unsigned int clear)
330{ 316{
317 struct usb_serial_port *port = tty->driver_data;
331 struct sierra_port_private *portdata; 318 struct sierra_port_private *portdata;
332 319
333 portdata = usb_get_serial_port_data(port); 320 portdata = usb_get_serial_port_data(port);
@@ -341,13 +328,7 @@ static int sierra_tiocmset(struct usb_serial_port *port, struct file *file,
341 portdata->rts_state = 0; 328 portdata->rts_state = 0;
342 if (clear & TIOCM_DTR) 329 if (clear & TIOCM_DTR)
343 portdata->dtr_state = 0; 330 portdata->dtr_state = 0;
344 return sierra_send_setup(port); 331 return sierra_send_setup(tty, port);
345}
346
347static int sierra_ioctl(struct usb_serial_port *port, struct file *file,
348 unsigned int cmd, unsigned long arg)
349{
350 return -ENOIOCTLCMD;
351} 332}
352 333
353static void sierra_outdat_callback(struct urb *urb) 334static void sierra_outdat_callback(struct urb *urb)
@@ -374,8 +355,8 @@ static void sierra_outdat_callback(struct urb *urb)
374} 355}
375 356
376/* Write */ 357/* Write */
377static int sierra_write(struct usb_serial_port *port, 358static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
378 const unsigned char *buf, int count) 359 const unsigned char *buf, int count)
379{ 360{
380 struct sierra_port_private *portdata = usb_get_serial_port_data(port); 361 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
381 struct usb_serial *serial = port->serial; 362 struct usb_serial *serial = port->serial;
@@ -463,7 +444,7 @@ static void sierra_indat_callback(struct urb *urb)
463 dbg("%s: nonzero status: %d on endpoint %02x.", 444 dbg("%s: nonzero status: %d on endpoint %02x.",
464 __func__, status, endpoint); 445 __func__, status, endpoint);
465 } else { 446 } else {
466 tty = port->tty; 447 tty = port->port.tty;
467 if (urb->actual_length) { 448 if (urb->actual_length) {
468 tty_buffer_request_room(tty, urb->actual_length); 449 tty_buffer_request_room(tty, urb->actual_length);
469 tty_insert_flip_string(tty, data, urb->actual_length); 450 tty_insert_flip_string(tty, data, urb->actual_length);
@@ -473,7 +454,7 @@ static void sierra_indat_callback(struct urb *urb)
473 } 454 }
474 455
475 /* Resubmit urb so we continue receiving */ 456 /* Resubmit urb so we continue receiving */
476 if (port->open_count && status != -ESHUTDOWN) { 457 if (port->port.count && status != -ESHUTDOWN) {
477 err = usb_submit_urb(urb, GFP_ATOMIC); 458 err = usb_submit_urb(urb, GFP_ATOMIC);
478 if (err) 459 if (err)
479 dev_err(&port->dev, "resubmit read urb failed." 460 dev_err(&port->dev, "resubmit read urb failed."
@@ -517,9 +498,9 @@ static void sierra_instat_callback(struct urb *urb)
517 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 498 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
518 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 499 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
519 500
520 if (port->tty && !C_CLOCAL(port->tty) && 501 if (port->port.tty && !C_CLOCAL(port->port.tty) &&
521 old_dcd_state && !portdata->dcd_state) 502 old_dcd_state && !portdata->dcd_state)
522 tty_hangup(port->tty); 503 tty_hangup(port->port.tty);
523 } else { 504 } else {
524 dbg("%s: type %x req %x", __func__, 505 dbg("%s: type %x req %x", __func__,
525 req_pkt->bRequestType, req_pkt->bRequest); 506 req_pkt->bRequestType, req_pkt->bRequest);
@@ -537,8 +518,9 @@ static void sierra_instat_callback(struct urb *urb)
537 } 518 }
538} 519}
539 520
540static int sierra_write_room(struct usb_serial_port *port) 521static int sierra_write_room(struct tty_struct *tty)
541{ 522{
523 struct usb_serial_port *port = tty->driver_data;
542 struct sierra_port_private *portdata = usb_get_serial_port_data(port); 524 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
543 unsigned long flags; 525 unsigned long flags;
544 526
@@ -557,22 +539,8 @@ static int sierra_write_room(struct usb_serial_port *port)
557 return 2048; 539 return 2048;
558} 540}
559 541
560static int sierra_chars_in_buffer(struct usb_serial_port *port) 542static int sierra_open(struct tty_struct *tty,
561{ 543 struct usb_serial_port *port, struct file *filp)
562 dbg("%s - port %d", __func__, port->number);
563
564 /*
565 * We can't really account for how much data we
566 * have sent out, but hasn't made it through to the
567 * device as we can't see the backend here, so just
568 * tell the tty layer that everything is flushed.
569 *
570 * FIXME: should walk the outstanding urbs info
571 */
572 return 0;
573}
574
575static int sierra_open(struct usb_serial_port *port, struct file *filp)
576{ 544{
577 struct sierra_port_private *portdata; 545 struct sierra_port_private *portdata;
578 struct usb_serial *serial = port->serial; 546 struct usb_serial *serial = port->serial;
@@ -612,9 +580,10 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
612 } 580 }
613 } 581 }
614 582
615 port->tty->low_latency = 1; 583 if (tty)
584 tty->low_latency = 1;
616 585
617 sierra_send_setup(port); 586 sierra_send_setup(tty, port);
618 587
619 /* start up the interrupt endpoint if we have one */ 588 /* start up the interrupt endpoint if we have one */
620 if (port->interrupt_in_urb) { 589 if (port->interrupt_in_urb) {
@@ -626,7 +595,8 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
626 return 0; 595 return 0;
627} 596}
628 597
629static void sierra_close(struct usb_serial_port *port, struct file *filp) 598static void sierra_close(struct tty_struct *tty,
599 struct usb_serial_port *port, struct file *filp)
630{ 600{
631 int i; 601 int i;
632 struct usb_serial *serial = port->serial; 602 struct usb_serial *serial = port->serial;
@@ -641,7 +611,7 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
641 if (serial->dev) { 611 if (serial->dev) {
642 mutex_lock(&serial->disc_mutex); 612 mutex_lock(&serial->disc_mutex);
643 if (!serial->disconnected) 613 if (!serial->disconnected)
644 sierra_send_setup(port); 614 sierra_send_setup(tty, port);
645 mutex_unlock(&serial->disc_mutex); 615 mutex_unlock(&serial->disc_mutex);
646 616
647 /* Stop reading/writing urbs */ 617 /* Stop reading/writing urbs */
@@ -651,7 +621,7 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
651 621
652 usb_kill_urb(port->interrupt_in_urb); 622 usb_kill_urb(port->interrupt_in_urb);
653 623
654 port->tty = NULL; 624 port->port.tty = NULL; /* FIXME */
655} 625}
656 626
657static int sierra_startup(struct usb_serial *serial) 627static int sierra_startup(struct usb_serial *serial)
@@ -754,12 +724,7 @@ static struct usb_serial_driver sierra_device = {
754 .close = sierra_close, 724 .close = sierra_close,
755 .write = sierra_write, 725 .write = sierra_write,
756 .write_room = sierra_write_room, 726 .write_room = sierra_write_room,
757 .chars_in_buffer = sierra_chars_in_buffer,
758 .throttle = sierra_rx_throttle,
759 .unthrottle = sierra_rx_unthrottle,
760 .ioctl = sierra_ioctl,
761 .set_termios = sierra_set_termios, 727 .set_termios = sierra_set_termios,
762 .break_ctl = sierra_break_ctl,
763 .tiocmget = sierra_tiocmget, 728 .tiocmget = sierra_tiocmget,
764 .tiocmset = sierra_tiocmset, 729 .tiocmset = sierra_tiocmset,
765 .attach = sierra_startup, 730 .attach = sierra_startup,