diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/serial/ssu100.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/serial/ssu100.c')
-rw-r--r-- | drivers/usb/serial/ssu100.c | 110 |
1 files changed, 36 insertions, 74 deletions
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index e986002b3844..87362e48796e 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -79,7 +79,6 @@ struct ssu100_port_private { | |||
79 | u8 shadowLSR; | 79 | u8 shadowLSR; |
80 | u8 shadowMSR; | 80 | u8 shadowMSR; |
81 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 81 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
82 | unsigned short max_packet_size; | ||
83 | struct async_icount icount; | 82 | struct async_icount icount; |
84 | }; | 83 | }; |
85 | 84 | ||
@@ -416,12 +415,34 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | |||
416 | return 0; | 415 | return 0; |
417 | } | 416 | } |
418 | 417 | ||
419 | static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | 418 | static int ssu100_get_icount(struct tty_struct *tty, |
420 | unsigned int cmd, unsigned long arg) | 419 | struct serial_icounter_struct *icount) |
421 | { | 420 | { |
422 | struct usb_serial_port *port = tty->driver_data; | 421 | struct usb_serial_port *port = tty->driver_data; |
423 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | 422 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); |
424 | void __user *user_arg = (void __user *)arg; | 423 | struct async_icount cnow = priv->icount; |
424 | |||
425 | icount->cts = cnow.cts; | ||
426 | icount->dsr = cnow.dsr; | ||
427 | icount->rng = cnow.rng; | ||
428 | icount->dcd = cnow.dcd; | ||
429 | icount->rx = cnow.rx; | ||
430 | icount->tx = cnow.tx; | ||
431 | icount->frame = cnow.frame; | ||
432 | icount->overrun = cnow.overrun; | ||
433 | icount->parity = cnow.parity; | ||
434 | icount->brk = cnow.brk; | ||
435 | icount->buf_overrun = cnow.buf_overrun; | ||
436 | |||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | |||
441 | |||
442 | static int ssu100_ioctl(struct tty_struct *tty, | ||
443 | unsigned int cmd, unsigned long arg) | ||
444 | { | ||
445 | struct usb_serial_port *port = tty->driver_data; | ||
425 | 446 | ||
426 | dbg("%s cmd 0x%04x", __func__, cmd); | 447 | dbg("%s cmd 0x%04x", __func__, cmd); |
427 | 448 | ||
@@ -433,27 +454,6 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | |||
433 | case TIOCMIWAIT: | 454 | case TIOCMIWAIT: |
434 | return wait_modem_info(port, arg); | 455 | return wait_modem_info(port, arg); |
435 | 456 | ||
436 | case TIOCGICOUNT: | ||
437 | { | ||
438 | struct serial_icounter_struct icount; | ||
439 | struct async_icount cnow = priv->icount; | ||
440 | memset(&icount, 0, sizeof(icount)); | ||
441 | icount.cts = cnow.cts; | ||
442 | icount.dsr = cnow.dsr; | ||
443 | icount.rng = cnow.rng; | ||
444 | icount.dcd = cnow.dcd; | ||
445 | icount.rx = cnow.rx; | ||
446 | icount.tx = cnow.tx; | ||
447 | icount.frame = cnow.frame; | ||
448 | icount.overrun = cnow.overrun; | ||
449 | icount.parity = cnow.parity; | ||
450 | icount.brk = cnow.brk; | ||
451 | icount.buf_overrun = cnow.buf_overrun; | ||
452 | if (copy_to_user(user_arg, &icount, sizeof(icount))) | ||
453 | return -EFAULT; | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | default: | 457 | default: |
458 | break; | 458 | break; |
459 | } | 459 | } |
@@ -463,36 +463,6 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | |||
463 | return -ENOIOCTLCMD; | 463 | return -ENOIOCTLCMD; |
464 | } | 464 | } |
465 | 465 | ||
466 | static void ssu100_set_max_packet_size(struct usb_serial_port *port) | ||
467 | { | ||
468 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
469 | struct usb_serial *serial = port->serial; | ||
470 | struct usb_device *udev = serial->dev; | ||
471 | |||
472 | struct usb_interface *interface = serial->interface; | ||
473 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; | ||
474 | |||
475 | unsigned num_endpoints; | ||
476 | int i; | ||
477 | unsigned long flags; | ||
478 | |||
479 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | ||
480 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | ||
481 | |||
482 | for (i = 0; i < num_endpoints; i++) { | ||
483 | dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1, | ||
484 | interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize); | ||
485 | ep_desc = &interface->cur_altsetting->endpoint[i].desc; | ||
486 | } | ||
487 | |||
488 | /* set max packet size based on descriptor */ | ||
489 | spin_lock_irqsave(&priv->status_lock, flags); | ||
490 | priv->max_packet_size = ep_desc->wMaxPacketSize; | ||
491 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
492 | |||
493 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | ||
494 | } | ||
495 | |||
496 | static int ssu100_attach(struct usb_serial *serial) | 466 | static int ssu100_attach(struct usb_serial *serial) |
497 | { | 467 | { |
498 | struct ssu100_port_private *priv; | 468 | struct ssu100_port_private *priv; |
@@ -510,12 +480,11 @@ static int ssu100_attach(struct usb_serial *serial) | |||
510 | spin_lock_init(&priv->status_lock); | 480 | spin_lock_init(&priv->status_lock); |
511 | init_waitqueue_head(&priv->delta_msr_wait); | 481 | init_waitqueue_head(&priv->delta_msr_wait); |
512 | usb_set_serial_port_data(port, priv); | 482 | usb_set_serial_port_data(port, priv); |
513 | ssu100_set_max_packet_size(port); | ||
514 | 483 | ||
515 | return ssu100_initdevice(serial->dev); | 484 | return ssu100_initdevice(serial->dev); |
516 | } | 485 | } |
517 | 486 | ||
518 | static int ssu100_tiocmget(struct tty_struct *tty, struct file *file) | 487 | static int ssu100_tiocmget(struct tty_struct *tty) |
519 | { | 488 | { |
520 | struct usb_serial_port *port = tty->driver_data; | 489 | struct usb_serial_port *port = tty->driver_data; |
521 | struct usb_device *dev = port->serial->dev; | 490 | struct usb_device *dev = port->serial->dev; |
@@ -548,7 +517,7 @@ mget_out: | |||
548 | return r; | 517 | return r; |
549 | } | 518 | } |
550 | 519 | ||
551 | static int ssu100_tiocmset(struct tty_struct *tty, struct file *file, | 520 | static int ssu100_tiocmset(struct tty_struct *tty, |
552 | unsigned int set, unsigned int clear) | 521 | unsigned int set, unsigned int clear) |
553 | { | 522 | { |
554 | struct usb_serial_port *port = tty->driver_data; | 523 | struct usb_serial_port *port = tty->driver_data; |
@@ -640,13 +609,14 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, | |||
640 | 609 | ||
641 | } | 610 | } |
642 | 611 | ||
643 | static int ssu100_process_packet(struct tty_struct *tty, | 612 | static int ssu100_process_packet(struct urb *urb, |
644 | struct usb_serial_port *port, | 613 | struct tty_struct *tty) |
645 | struct ssu100_port_private *priv, | ||
646 | char *packet, int len) | ||
647 | { | 614 | { |
648 | int i; | 615 | struct usb_serial_port *port = urb->context; |
616 | char *packet = (char *)urb->transfer_buffer; | ||
649 | char flag = TTY_NORMAL; | 617 | char flag = TTY_NORMAL; |
618 | u32 len = urb->actual_length; | ||
619 | int i; | ||
650 | char *ch; | 620 | char *ch; |
651 | 621 | ||
652 | dbg("%s - port %d", __func__, port->number); | 622 | dbg("%s - port %d", __func__, port->number); |
@@ -684,12 +654,8 @@ static int ssu100_process_packet(struct tty_struct *tty, | |||
684 | static void ssu100_process_read_urb(struct urb *urb) | 654 | static void ssu100_process_read_urb(struct urb *urb) |
685 | { | 655 | { |
686 | struct usb_serial_port *port = urb->context; | 656 | struct usb_serial_port *port = urb->context; |
687 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
688 | char *data = (char *)urb->transfer_buffer; | ||
689 | struct tty_struct *tty; | 657 | struct tty_struct *tty; |
690 | int count = 0; | 658 | int count; |
691 | int i; | ||
692 | int len; | ||
693 | 659 | ||
694 | dbg("%s", __func__); | 660 | dbg("%s", __func__); |
695 | 661 | ||
@@ -697,10 +663,7 @@ static void ssu100_process_read_urb(struct urb *urb) | |||
697 | if (!tty) | 663 | if (!tty) |
698 | return; | 664 | return; |
699 | 665 | ||
700 | for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { | 666 | count = ssu100_process_packet(urb, tty); |
701 | len = min_t(int, urb->actual_length - i, priv->max_packet_size); | ||
702 | count += ssu100_process_packet(tty, port, priv, &data[i], len); | ||
703 | } | ||
704 | 667 | ||
705 | if (count) | 668 | if (count) |
706 | tty_flip_buffer_push(tty); | 669 | tty_flip_buffer_push(tty); |
@@ -716,8 +679,6 @@ static struct usb_serial_driver ssu100_device = { | |||
716 | .id_table = id_table, | 679 | .id_table = id_table, |
717 | .usb_driver = &ssu100_driver, | 680 | .usb_driver = &ssu100_driver, |
718 | .num_ports = 1, | 681 | .num_ports = 1, |
719 | .bulk_in_size = 256, | ||
720 | .bulk_out_size = 256, | ||
721 | .open = ssu100_open, | 682 | .open = ssu100_open, |
722 | .close = ssu100_close, | 683 | .close = ssu100_close, |
723 | .attach = ssu100_attach, | 684 | .attach = ssu100_attach, |
@@ -726,6 +687,7 @@ static struct usb_serial_driver ssu100_device = { | |||
726 | .process_read_urb = ssu100_process_read_urb, | 687 | .process_read_urb = ssu100_process_read_urb, |
727 | .tiocmget = ssu100_tiocmget, | 688 | .tiocmget = ssu100_tiocmget, |
728 | .tiocmset = ssu100_tiocmset, | 689 | .tiocmset = ssu100_tiocmset, |
690 | .get_icount = ssu100_get_icount, | ||
729 | .ioctl = ssu100_ioctl, | 691 | .ioctl = ssu100_ioctl, |
730 | .set_termios = ssu100_set_termios, | 692 | .set_termios = ssu100_set_termios, |
731 | .disconnect = usb_serial_generic_disconnect, | 693 | .disconnect = usb_serial_generic_disconnect, |