diff options
Diffstat (limited to 'drivers/usb/serial/oti6858.c')
-rw-r--r-- | drivers/usb/serial/oti6858.c | 119 |
1 files changed, 48 insertions, 71 deletions
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index a9625c180dc3..069d276a5276 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -140,22 +140,23 @@ struct oti6858_control_pkt { | |||
140 | && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt) ) | 140 | && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt) ) |
141 | 141 | ||
142 | /* function prototypes */ | 142 | /* function prototypes */ |
143 | static int oti6858_open(struct usb_serial_port *port, struct file *filp); | 143 | static int oti6858_open(struct tty_struct *tty, |
144 | static void oti6858_close(struct usb_serial_port *port, struct file *filp); | 144 | struct usb_serial_port *port, struct file *filp); |
145 | static void oti6858_set_termios(struct usb_serial_port *port, | 145 | static void oti6858_close(struct tty_struct *tty, |
146 | struct ktermios *old); | 146 | struct usb_serial_port *port, struct file *filp); |
147 | static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, | 147 | static void oti6858_set_termios(struct tty_struct *tty, |
148 | struct usb_serial_port *port, struct ktermios *old); | ||
149 | static int oti6858_ioctl(struct tty_struct *tty, struct file *file, | ||
148 | unsigned int cmd, unsigned long arg); | 150 | unsigned int cmd, unsigned long arg); |
149 | static void oti6858_read_int_callback(struct urb *urb); | 151 | static void oti6858_read_int_callback(struct urb *urb); |
150 | static void oti6858_read_bulk_callback(struct urb *urb); | 152 | static void oti6858_read_bulk_callback(struct urb *urb); |
151 | static void oti6858_write_bulk_callback(struct urb *urb); | 153 | static void oti6858_write_bulk_callback(struct urb *urb); |
152 | static int oti6858_write(struct usb_serial_port *port, | 154 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, |
153 | const unsigned char *buf, int count); | 155 | const unsigned char *buf, int count); |
154 | static int oti6858_write_room(struct usb_serial_port *port); | 156 | static int oti6858_write_room(struct tty_struct *tty); |
155 | static void oti6858_break_ctl(struct usb_serial_port *port, int break_state); | 157 | static int oti6858_chars_in_buffer(struct tty_struct *tty); |
156 | static int oti6858_chars_in_buffer(struct usb_serial_port *port); | 158 | static int oti6858_tiocmget(struct tty_struct *tty, struct file *file); |
157 | static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file); | 159 | static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, |
158 | static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file, | ||
159 | unsigned int set, unsigned int clear); | 160 | unsigned int set, unsigned int clear); |
160 | static int oti6858_startup(struct usb_serial *serial); | 161 | static int oti6858_startup(struct usb_serial *serial); |
161 | static void oti6858_shutdown(struct usb_serial *serial); | 162 | static void oti6858_shutdown(struct usb_serial *serial); |
@@ -184,7 +185,6 @@ static struct usb_serial_driver oti6858_device = { | |||
184 | .close = oti6858_close, | 185 | .close = oti6858_close, |
185 | .write = oti6858_write, | 186 | .write = oti6858_write, |
186 | .ioctl = oti6858_ioctl, | 187 | .ioctl = oti6858_ioctl, |
187 | .break_ctl = oti6858_break_ctl, | ||
188 | .set_termios = oti6858_set_termios, | 188 | .set_termios = oti6858_set_termios, |
189 | .tiocmget = oti6858_tiocmget, | 189 | .tiocmget = oti6858_tiocmget, |
190 | .tiocmset = oti6858_tiocmset, | 190 | .tiocmset = oti6858_tiocmset, |
@@ -395,7 +395,7 @@ static int oti6858_startup(struct usb_serial *serial) | |||
395 | return -ENOMEM; | 395 | return -ENOMEM; |
396 | } | 396 | } |
397 | 397 | ||
398 | static int oti6858_write(struct usb_serial_port *port, | 398 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, |
399 | const unsigned char *buf, int count) | 399 | const unsigned char *buf, int count) |
400 | { | 400 | { |
401 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 401 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
@@ -413,8 +413,9 @@ static int oti6858_write(struct usb_serial_port *port, | |||
413 | return count; | 413 | return count; |
414 | } | 414 | } |
415 | 415 | ||
416 | static int oti6858_write_room(struct usb_serial_port *port) | 416 | static int oti6858_write_room(struct tty_struct *tty) |
417 | { | 417 | { |
418 | struct usb_serial_port *port = tty->driver_data; | ||
418 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 419 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
419 | int room = 0; | 420 | int room = 0; |
420 | unsigned long flags; | 421 | unsigned long flags; |
@@ -428,8 +429,9 @@ static int oti6858_write_room(struct usb_serial_port *port) | |||
428 | return room; | 429 | return room; |
429 | } | 430 | } |
430 | 431 | ||
431 | static int oti6858_chars_in_buffer(struct usb_serial_port *port) | 432 | static int oti6858_chars_in_buffer(struct tty_struct *tty) |
432 | { | 433 | { |
434 | struct usb_serial_port *port = tty->driver_data; | ||
433 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 435 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
434 | int chars = 0; | 436 | int chars = 0; |
435 | unsigned long flags; | 437 | unsigned long flags; |
@@ -443,8 +445,8 @@ static int oti6858_chars_in_buffer(struct usb_serial_port *port) | |||
443 | return chars; | 445 | return chars; |
444 | } | 446 | } |
445 | 447 | ||
446 | static void oti6858_set_termios(struct usb_serial_port *port, | 448 | static void oti6858_set_termios(struct tty_struct *tty, |
447 | struct ktermios *old_termios) | 449 | struct usb_serial_port *port, struct ktermios *old_termios) |
448 | { | 450 | { |
449 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 451 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
450 | unsigned long flags; | 452 | unsigned long flags; |
@@ -455,22 +457,22 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
455 | 457 | ||
456 | dbg("%s(port = %d)", __func__, port->number); | 458 | dbg("%s(port = %d)", __func__, port->number); |
457 | 459 | ||
458 | if (!port->tty || !port->tty->termios) { | 460 | if (!tty) { |
459 | dbg("%s(): no tty structures", __func__); | 461 | dbg("%s(): no tty structures", __func__); |
460 | return; | 462 | return; |
461 | } | 463 | } |
462 | 464 | ||
463 | spin_lock_irqsave(&priv->lock, flags); | 465 | spin_lock_irqsave(&priv->lock, flags); |
464 | if (!priv->flags.termios_initialized) { | 466 | if (!priv->flags.termios_initialized) { |
465 | *(port->tty->termios) = tty_std_termios; | 467 | *(tty->termios) = tty_std_termios; |
466 | port->tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; | 468 | tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; |
469 | tty->termios->c_ispeed = 38400; | ||
470 | tty->termios->c_ospeed = 38400; | ||
467 | priv->flags.termios_initialized = 1; | 471 | priv->flags.termios_initialized = 1; |
468 | port->tty->termios->c_ispeed = 38400; | ||
469 | port->tty->termios->c_ospeed = 38400; | ||
470 | } | 472 | } |
471 | spin_unlock_irqrestore(&priv->lock, flags); | 473 | spin_unlock_irqrestore(&priv->lock, flags); |
472 | 474 | ||
473 | cflag = port->tty->termios->c_cflag; | 475 | cflag = tty->termios->c_cflag; |
474 | 476 | ||
475 | spin_lock_irqsave(&priv->lock, flags); | 477 | spin_lock_irqsave(&priv->lock, flags); |
476 | divisor = priv->pending_setup.divisor; | 478 | divisor = priv->pending_setup.divisor; |
@@ -500,7 +502,7 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
500 | * guarantee that any other baud rate will work (especially | 502 | * guarantee that any other baud rate will work (especially |
501 | * the higher ones) | 503 | * the higher ones) |
502 | */ | 504 | */ |
503 | br = tty_get_baud_rate(port->tty); | 505 | br = tty_get_baud_rate(tty); |
504 | if (br == 0) { | 506 | if (br == 0) { |
505 | divisor = 0; | 507 | divisor = 0; |
506 | } else { | 508 | } else { |
@@ -511,7 +513,7 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
511 | new_divisor = (96000000 + 8 * br) / (16 * br); | 513 | new_divisor = (96000000 + 8 * br) / (16 * br); |
512 | real_br = 96000000 / (16 * new_divisor); | 514 | real_br = 96000000 / (16 * new_divisor); |
513 | divisor = cpu_to_le16(new_divisor); | 515 | divisor = cpu_to_le16(new_divisor); |
514 | tty_encode_baud_rate(port->tty, real_br, real_br); | 516 | tty_encode_baud_rate(tty, real_br, real_br); |
515 | } | 517 | } |
516 | 518 | ||
517 | frame_fmt &= ~FMT_STOP_BITS_MASK; | 519 | frame_fmt &= ~FMT_STOP_BITS_MASK; |
@@ -564,7 +566,8 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
564 | spin_unlock_irqrestore(&priv->lock, flags); | 566 | spin_unlock_irqrestore(&priv->lock, flags); |
565 | } | 567 | } |
566 | 568 | ||
567 | static int oti6858_open(struct usb_serial_port *port, struct file *filp) | 569 | static int oti6858_open(struct tty_struct *tty, |
570 | struct usb_serial_port *port, struct file *filp) | ||
568 | { | 571 | { |
569 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 572 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
570 | struct ktermios tmp_termios; | 573 | struct ktermios tmp_termios; |
@@ -578,7 +581,7 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp) | |||
578 | usb_clear_halt(serial->dev, port->write_urb->pipe); | 581 | usb_clear_halt(serial->dev, port->write_urb->pipe); |
579 | usb_clear_halt(serial->dev, port->read_urb->pipe); | 582 | usb_clear_halt(serial->dev, port->read_urb->pipe); |
580 | 583 | ||
581 | if (port->open_count != 1) | 584 | if (port->port.count != 1) |
582 | return 0; | 585 | return 0; |
583 | 586 | ||
584 | if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { | 587 | if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { |
@@ -617,18 +620,19 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp) | |||
617 | if (result != 0) { | 620 | if (result != 0) { |
618 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" | 621 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" |
619 | " with error %d\n", __func__, result); | 622 | " with error %d\n", __func__, result); |
620 | oti6858_close(port, NULL); | 623 | oti6858_close(tty, port, NULL); |
621 | return -EPROTO; | 624 | return -EPROTO; |
622 | } | 625 | } |
623 | 626 | ||
624 | /* setup termios */ | 627 | /* setup termios */ |
625 | if (port->tty) | 628 | if (tty) |
626 | oti6858_set_termios(port, &tmp_termios); | 629 | oti6858_set_termios(tty, port, &tmp_termios); |
627 | 630 | ||
628 | return 0; | 631 | return 0; |
629 | } | 632 | } |
630 | 633 | ||
631 | static void oti6858_close(struct usb_serial_port *port, struct file *filp) | 634 | static void oti6858_close(struct tty_struct *tty, |
635 | struct usb_serial_port *port, struct file *filp) | ||
632 | { | 636 | { |
633 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 637 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
634 | unsigned long flags; | 638 | unsigned long flags; |
@@ -641,7 +645,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
641 | spin_lock_irqsave(&priv->lock, flags); | 645 | spin_lock_irqsave(&priv->lock, flags); |
642 | timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */ | 646 | timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */ |
643 | init_waitqueue_entry(&wait, current); | 647 | init_waitqueue_entry(&wait, current); |
644 | add_wait_queue(&port->tty->write_wait, &wait); | 648 | add_wait_queue(&tty->write_wait, &wait); |
645 | dbg("%s(): entering wait loop", __func__); | 649 | dbg("%s(): entering wait loop", __func__); |
646 | for (;;) { | 650 | for (;;) { |
647 | set_current_state(TASK_INTERRUPTIBLE); | 651 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -654,7 +658,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
654 | spin_lock_irqsave(&priv->lock, flags); | 658 | spin_lock_irqsave(&priv->lock, flags); |
655 | } | 659 | } |
656 | set_current_state(TASK_RUNNING); | 660 | set_current_state(TASK_RUNNING); |
657 | remove_wait_queue(&port->tty->write_wait, &wait); | 661 | remove_wait_queue(&tty->write_wait, &wait); |
658 | dbg("%s(): after wait loop", __func__); | 662 | dbg("%s(): after wait loop", __func__); |
659 | 663 | ||
660 | /* clear out any remaining data in the buffer */ | 664 | /* clear out any remaining data in the buffer */ |
@@ -669,7 +673,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
669 | /* data is in the buffer to compute a delay */ | 673 | /* data is in the buffer to compute a delay */ |
670 | /* that is not unnecessarily long) */ | 674 | /* that is not unnecessarily long) */ |
671 | /* FIXME | 675 | /* FIXME |
672 | bps = tty_get_baud_rate(port->tty); | 676 | bps = tty_get_baud_rate(tty); |
673 | if (bps > 1200) | 677 | if (bps > 1200) |
674 | timeout = max((HZ*2560)/bps,HZ/10); | 678 | timeout = max((HZ*2560)/bps,HZ/10); |
675 | else | 679 | else |
@@ -690,7 +694,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
690 | usb_kill_urb(port->interrupt_in_urb); | 694 | usb_kill_urb(port->interrupt_in_urb); |
691 | 695 | ||
692 | /* | 696 | /* |
693 | if (port->tty && (port->tty->termios->c_cflag) & HUPCL) { | 697 | if (tty && (tty->termios->c_cflag) & HUPCL) { |
694 | // drop DTR and RTS | 698 | // drop DTR and RTS |
695 | spin_lock_irqsave(&priv->lock, flags); | 699 | spin_lock_irqsave(&priv->lock, flags); |
696 | priv->pending_setup.control &= ~CONTROL_MASK; | 700 | priv->pending_setup.control &= ~CONTROL_MASK; |
@@ -699,9 +703,10 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
699 | */ | 703 | */ |
700 | } | 704 | } |
701 | 705 | ||
702 | static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file, | 706 | static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, |
703 | unsigned int set, unsigned int clear) | 707 | unsigned int set, unsigned int clear) |
704 | { | 708 | { |
709 | struct usb_serial_port *port = tty->driver_data; | ||
705 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 710 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
706 | unsigned long flags; | 711 | unsigned long flags; |
707 | u8 control; | 712 | u8 control; |
@@ -732,8 +737,9 @@ static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file, | |||
732 | return 0; | 737 | return 0; |
733 | } | 738 | } |
734 | 739 | ||
735 | static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file) | 740 | static int oti6858_tiocmget(struct tty_struct *tty, struct file *file) |
736 | { | 741 | { |
742 | struct usb_serial_port *port = tty->driver_data; | ||
737 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 743 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
738 | unsigned long flags; | 744 | unsigned long flags; |
739 | unsigned pin_state; | 745 | unsigned pin_state; |
@@ -802,26 +808,15 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | |||
802 | return 0; | 808 | return 0; |
803 | } | 809 | } |
804 | 810 | ||
805 | static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, | 811 | static int oti6858_ioctl(struct tty_struct *tty, struct file *file, |
806 | unsigned int cmd, unsigned long arg) | 812 | unsigned int cmd, unsigned long arg) |
807 | { | 813 | { |
808 | void __user *user_arg = (void __user *) arg; | 814 | struct usb_serial_port *port = tty->driver_data; |
809 | unsigned int x; | ||
810 | 815 | ||
811 | dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)", | 816 | dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)", |
812 | __func__, port->number, cmd, arg); | 817 | __func__, port->number, cmd, arg); |
813 | 818 | ||
814 | switch (cmd) { | 819 | switch (cmd) { |
815 | case TIOCMBIS: | ||
816 | if (copy_from_user(&x, user_arg, sizeof(x))) | ||
817 | return -EFAULT; | ||
818 | return oti6858_tiocmset(port, NULL, x, 0); | ||
819 | |||
820 | case TIOCMBIC: | ||
821 | if (copy_from_user(&x, user_arg, sizeof(x))) | ||
822 | return -EFAULT; | ||
823 | return oti6858_tiocmset(port, NULL, 0, x); | ||
824 | |||
825 | case TIOCMIWAIT: | 820 | case TIOCMIWAIT: |
826 | dbg("%s(): TIOCMIWAIT", __func__); | 821 | dbg("%s(): TIOCMIWAIT", __func__); |
827 | return wait_modem_info(port, arg); | 822 | return wait_modem_info(port, arg); |
@@ -834,24 +829,6 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, | |||
834 | return -ENOIOCTLCMD; | 829 | return -ENOIOCTLCMD; |
835 | } | 830 | } |
836 | 831 | ||
837 | static void oti6858_break_ctl(struct usb_serial_port *port, int break_state) | ||
838 | { | ||
839 | int state; | ||
840 | |||
841 | dbg("%s(port = %d)", __func__, port->number); | ||
842 | |||
843 | state = (break_state == 0) ? 0 : 1; | ||
844 | dbg("%s(): turning break %s", __func__, state ? "on" : "off"); | ||
845 | |||
846 | /* FIXME */ | ||
847 | /* | ||
848 | result = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), | ||
849 | BREAK_REQUEST, BREAK_REQUEST_TYPE, state, | ||
850 | 0, NULL, 0, 100); | ||
851 | if (result != 0) | ||
852 | dbg("%s(): error sending break", __func__); | ||
853 | */ | ||
854 | } | ||
855 | 832 | ||
856 | static void oti6858_shutdown(struct usb_serial *serial) | 833 | static void oti6858_shutdown(struct usb_serial *serial) |
857 | { | 834 | { |
@@ -1002,7 +979,7 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
1002 | spin_unlock_irqrestore(&priv->lock, flags); | 979 | spin_unlock_irqrestore(&priv->lock, flags); |
1003 | 980 | ||
1004 | if (status != 0) { | 981 | if (status != 0) { |
1005 | if (!port->open_count) { | 982 | if (!port->port.count) { |
1006 | dbg("%s(): port is closed, exiting", __func__); | 983 | dbg("%s(): port is closed, exiting", __func__); |
1007 | return; | 984 | return; |
1008 | } | 985 | } |
@@ -1020,14 +997,14 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
1020 | return; | 997 | return; |
1021 | } | 998 | } |
1022 | 999 | ||
1023 | tty = port->tty; | 1000 | tty = port->port.tty; |
1024 | if (tty != NULL && urb->actual_length > 0) { | 1001 | if (tty != NULL && urb->actual_length > 0) { |
1025 | tty_insert_flip_string(tty, data, urb->actual_length); | 1002 | tty_insert_flip_string(tty, data, urb->actual_length); |
1026 | tty_flip_buffer_push(tty); | 1003 | tty_flip_buffer_push(tty); |
1027 | } | 1004 | } |
1028 | 1005 | ||
1029 | // schedule the interrupt urb if we are still open */ | 1006 | // schedule the interrupt urb if we are still open */ |
1030 | if (port->open_count != 0) { | 1007 | if (port->port.count != 0) { |
1031 | port->interrupt_in_urb->dev = port->serial->dev; | 1008 | port->interrupt_in_urb->dev = port->serial->dev; |
1032 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 1009 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
1033 | if (result != 0) { | 1010 | if (result != 0) { |