aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2010-05-15 11:53:46 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:48 -0400
commit6b6962f9c489ecfa43ae27eb798c46717e203322 (patch)
tree80efc634058a09fe1b6c95fe5c8cfc8e94c2d4dd /drivers
parent695aaae684e249f9f0e7f1ed4caafa0687dbfa5b (diff)
USB: ipaq: reimplement using generic framework
Kill custom fifo, read and write implementations (single-urb and fifo, but still maintained list of 256*256b urb buffers per port). Compile-only tested. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/serial/ipaq.c333
-rw-r--r--drivers/usb/serial/ipaq.h54
2 files changed, 10 insertions, 377 deletions
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 87b11461bf11..28913fa95fb7 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -56,7 +56,6 @@
56#include <linux/uaccess.h> 56#include <linux/uaccess.h>
57#include <linux/usb.h> 57#include <linux/usb.h>
58#include <linux/usb/serial.h> 58#include <linux/usb/serial.h>
59#include "ipaq.h"
60 59
61#define KP_RETRIES 100 60#define KP_RETRIES 100
62 61
@@ -64,7 +63,7 @@
64 * Version Information 63 * Version Information
65 */ 64 */
66 65
67#define DRIVER_VERSION "v0.5" 66#define DRIVER_VERSION "v1.0"
68#define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>" 67#define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"
69#define DRIVER_DESC "USB PocketPC PDA driver" 68#define DRIVER_DESC "USB PocketPC PDA driver"
70 69
@@ -76,20 +75,8 @@ static int initial_wait;
76/* Function prototypes for an ipaq */ 75/* Function prototypes for an ipaq */
77static int ipaq_open(struct tty_struct *tty, 76static int ipaq_open(struct tty_struct *tty,
78 struct usb_serial_port *port); 77 struct usb_serial_port *port);
79static void ipaq_close(struct usb_serial_port *port);
80static int ipaq_calc_num_ports(struct usb_serial *serial); 78static int ipaq_calc_num_ports(struct usb_serial *serial);
81static int ipaq_startup(struct usb_serial *serial); 79static int ipaq_startup(struct usb_serial *serial);
82static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
83 const unsigned char *buf, int count);
84static int ipaq_write_bulk(struct usb_serial_port *port,
85 const unsigned char *buf, int count);
86static void ipaq_write_gather(struct usb_serial_port *port);
87static void ipaq_read_bulk_callback(struct urb *urb);
88static void ipaq_write_bulk_callback(struct urb *urb);
89static int ipaq_write_room(struct tty_struct *tty);
90static int ipaq_chars_in_buffer(struct tty_struct *tty);
91static void ipaq_destroy_lists(struct usb_serial_port *port);
92
93 80
94static struct usb_device_id ipaq_id_table [] = { 81static struct usb_device_id ipaq_id_table [] = {
95 /* The first entry is a placeholder for the insmod-specified device */ 82 /* The first entry is a placeholder for the insmod-specified device */
@@ -558,7 +545,7 @@ static struct usb_driver ipaq_driver = {
558 .probe = usb_serial_probe, 545 .probe = usb_serial_probe,
559 .disconnect = usb_serial_disconnect, 546 .disconnect = usb_serial_disconnect,
560 .id_table = ipaq_id_table, 547 .id_table = ipaq_id_table,
561 .no_dynamic_id = 1, 548 .no_dynamic_id = 1,
562}; 549};
563 550
564 551
@@ -569,67 +556,24 @@ static struct usb_serial_driver ipaq_device = {
569 .name = "ipaq", 556 .name = "ipaq",
570 }, 557 },
571 .description = "PocketPC PDA", 558 .description = "PocketPC PDA",
572 .usb_driver = &ipaq_driver, 559 .usb_driver = &ipaq_driver,
573 .id_table = ipaq_id_table, 560 .id_table = ipaq_id_table,
574 .bulk_in_size = URBDATA_SIZE, 561 .bulk_in_size = 256,
575 .bulk_out_size = URBDATA_SIZE, 562 .bulk_out_size = 256,
576 .open = ipaq_open, 563 .open = ipaq_open,
577 .close = ipaq_close,
578 .attach = ipaq_startup, 564 .attach = ipaq_startup,
579 .calc_num_ports = ipaq_calc_num_ports, 565 .calc_num_ports = ipaq_calc_num_ports,
580 .write = ipaq_write,
581 .write_room = ipaq_write_room,
582 .chars_in_buffer = ipaq_chars_in_buffer,
583 .read_bulk_callback = ipaq_read_bulk_callback,
584 .write_bulk_callback = ipaq_write_bulk_callback,
585}; 566};
586 567
587static spinlock_t write_list_lock;
588static int bytes_in;
589static int bytes_out;
590
591static int ipaq_open(struct tty_struct *tty, 568static int ipaq_open(struct tty_struct *tty,
592 struct usb_serial_port *port) 569 struct usb_serial_port *port)
593{ 570{
594 struct usb_serial *serial = port->serial; 571 struct usb_serial *serial = port->serial;
595 struct ipaq_private *priv; 572 int result = 0;
596 struct ipaq_packet *pkt;
597 int i, result = 0;
598 int retries = connect_retries; 573 int retries = connect_retries;
599 574
600 dbg("%s - port %d", __func__, port->number); 575 dbg("%s - port %d", __func__, port->number);
601 576
602 bytes_in = 0;
603 bytes_out = 0;
604 priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
605 if (priv == NULL) {
606 dev_err(&port->dev, "%s - Out of memory\n", __func__);
607 return -ENOMEM;
608 }
609 usb_set_serial_port_data(port, priv);
610 priv->active = 0;
611 priv->queue_len = 0;
612 priv->free_len = 0;
613 INIT_LIST_HEAD(&priv->queue);
614 INIT_LIST_HEAD(&priv->freelist);
615
616 for (i = 0; i < URBDATA_QUEUE_MAX / PACKET_SIZE; i++) {
617 pkt = kmalloc(sizeof(struct ipaq_packet), GFP_KERNEL);
618 if (pkt == NULL)
619 goto enomem;
620
621 pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL);
622 if (pkt->data == NULL) {
623 kfree(pkt);
624 goto enomem;
625 }
626 pkt->len = 0;
627 pkt->written = 0;
628 INIT_LIST_HEAD(&pkt->list);
629 list_add(&pkt->list, &priv->freelist);
630 priv->free_len += PACKET_SIZE;
631 }
632
633 msleep(1000*initial_wait); 577 msleep(1000*initial_wait);
634 578
635 /* 579 /*
@@ -639,7 +583,6 @@ static int ipaq_open(struct tty_struct *tty,
639 * through. Since this has a reasonably high failure rate, we retry 583 * through. Since this has a reasonably high failure rate, we retry
640 * several times. 584 * several times.
641 */ 585 */
642
643 while (retries--) { 586 while (retries--) {
644 result = usb_control_msg(serial->dev, 587 result = usb_control_msg(serial->dev,
645 usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, 588 usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
@@ -649,269 +592,15 @@ static int ipaq_open(struct tty_struct *tty,
649 592
650 msleep(1000); 593 msleep(1000);
651 } 594 }
652
653 if (!retries && result) { 595 if (!retries && result) {
654 dev_err(&port->dev, "%s - failed doing control urb, error %d\n", __func__, result); 596 dev_err(&port->dev, "%s - failed doing control urb, error %d\n",
655 goto error; 597 __func__, result);
656 } 598 return result;
657
658 /* Start reading from the device */
659 usb_fill_bulk_urb(port->read_urb, serial->dev,
660 usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
661 port->read_urb->transfer_buffer,
662 port->read_urb->transfer_buffer_length,
663 ipaq_read_bulk_callback, port);
664
665 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
666 if (result) {
667 dev_err(&port->dev,
668 "%s - failed submitting read urb, error %d\n",
669 __func__, result);
670 goto error;
671 }
672
673 return 0;
674
675enomem:
676 result = -ENOMEM;
677 dev_err(&port->dev, "%s - Out of memory\n", __func__);
678error:
679 ipaq_destroy_lists(port);
680 kfree(priv);
681 return result;
682}
683
684
685static void ipaq_close(struct usb_serial_port *port)
686{
687 struct ipaq_private *priv = usb_get_serial_port_data(port);
688
689 dbg("%s - port %d", __func__, port->number);
690
691 /*
692 * shut down bulk read and write
693 */
694 usb_kill_urb(port->write_urb);
695 usb_kill_urb(port->read_urb);
696 ipaq_destroy_lists(port);
697 kfree(priv);
698 usb_set_serial_port_data(port, NULL);
699
700 /* Uncomment the following line if you want to see some statistics
701 * in your syslog */
702 /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
703}
704
705static void ipaq_read_bulk_callback(struct urb *urb)
706{
707 struct usb_serial_port *port = urb->context;
708 struct tty_struct *tty;
709 unsigned char *data = urb->transfer_buffer;
710 int result;
711 int status = urb->status;
712
713 dbg("%s - port %d", __func__, port->number);
714
715 if (status) {
716 dbg("%s - nonzero read bulk status received: %d",
717 __func__, status);
718 return;
719 } 599 }
720 600
721 usb_serial_debug_data(debug, &port->dev, __func__, 601 return usb_serial_generic_open(tty, port);
722 urb->actual_length, data);
723
724 tty = tty_port_tty_get(&port->port);
725 if (tty && urb->actual_length) {
726 tty_insert_flip_string(tty, data, urb->actual_length);
727 tty_flip_buffer_push(tty);
728 bytes_in += urb->actual_length;
729 }
730 tty_kref_put(tty);
731
732 /* Continue trying to always read */
733 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
734 usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
735 port->read_urb->transfer_buffer,
736 port->read_urb->transfer_buffer_length,
737 ipaq_read_bulk_callback, port);
738 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
739 if (result)
740 dev_err(&port->dev,
741 "%s - failed resubmitting read urb, error %d\n",
742 __func__, result);
743 return;
744} 602}
745 603
746static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
747 const unsigned char *buf, int count)
748{
749 const unsigned char *current_position = buf;
750 int bytes_sent = 0;
751 int transfer_size;
752
753 dbg("%s - port %d", __func__, port->number);
754
755 while (count > 0) {
756 transfer_size = min(count, PACKET_SIZE);
757 if (ipaq_write_bulk(port, current_position, transfer_size))
758 break;
759 current_position += transfer_size;
760 bytes_sent += transfer_size;
761 count -= transfer_size;
762 bytes_out += transfer_size;
763 }
764
765 return bytes_sent;
766}
767
768static int ipaq_write_bulk(struct usb_serial_port *port,
769 const unsigned char *buf, int count)
770{
771 struct ipaq_private *priv = usb_get_serial_port_data(port);
772 struct ipaq_packet *pkt = NULL;
773 int result = 0;
774 unsigned long flags;
775
776 if (priv->free_len <= 0) {
777 dbg("%s - we're stuffed", __func__);
778 return -EAGAIN;
779 }
780
781 spin_lock_irqsave(&write_list_lock, flags);
782 if (!list_empty(&priv->freelist)) {
783 pkt = list_entry(priv->freelist.next, struct ipaq_packet, list);
784 list_del(&pkt->list);
785 priv->free_len -= PACKET_SIZE;
786 }
787 spin_unlock_irqrestore(&write_list_lock, flags);
788 if (pkt == NULL) {
789 dbg("%s - we're stuffed", __func__);
790 return -EAGAIN;
791 }
792
793 memcpy(pkt->data, buf, count);
794 usb_serial_debug_data(debug, &port->dev, __func__, count, pkt->data);
795
796 pkt->len = count;
797 pkt->written = 0;
798 spin_lock_irqsave(&write_list_lock, flags);
799 list_add_tail(&pkt->list, &priv->queue);
800 priv->queue_len += count;
801 if (priv->active == 0) {
802 priv->active = 1;
803 ipaq_write_gather(port);
804 spin_unlock_irqrestore(&write_list_lock, flags);
805 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
806 if (result)
807 dev_err(&port->dev,
808 "%s - failed submitting write urb, error %d\n",
809 __func__, result);
810 } else {
811 spin_unlock_irqrestore(&write_list_lock, flags);
812 }
813 return result;
814}
815
816static void ipaq_write_gather(struct usb_serial_port *port)
817{
818 struct ipaq_private *priv = usb_get_serial_port_data(port);
819 struct usb_serial *serial = port->serial;
820 int count, room;
821 struct ipaq_packet *pkt, *tmp;
822 struct urb *urb = port->write_urb;
823
824 room = URBDATA_SIZE;
825 list_for_each_entry_safe(pkt, tmp, &priv->queue, list) {
826 count = min(room, (int)(pkt->len - pkt->written));
827 memcpy(urb->transfer_buffer + (URBDATA_SIZE - room),
828 pkt->data + pkt->written, count);
829 room -= count;
830 pkt->written += count;
831 priv->queue_len -= count;
832 if (pkt->written == pkt->len) {
833 list_move(&pkt->list, &priv->freelist);
834 priv->free_len += PACKET_SIZE;
835 }
836 if (room == 0)
837 break;
838 }
839
840 count = URBDATA_SIZE - room;
841 usb_fill_bulk_urb(port->write_urb, serial->dev,
842 usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
843 port->write_urb->transfer_buffer, count,
844 ipaq_write_bulk_callback, port);
845 return;
846}
847
848static void ipaq_write_bulk_callback(struct urb *urb)
849{
850 struct usb_serial_port *port = urb->context;
851 struct ipaq_private *priv = usb_get_serial_port_data(port);
852 unsigned long flags;
853 int result;
854 int status = urb->status;
855
856 dbg("%s - port %d", __func__, port->number);
857
858 if (status) {
859 dbg("%s - nonzero write bulk status received: %d",
860 __func__, status);
861 return;
862 }
863
864 spin_lock_irqsave(&write_list_lock, flags);
865 if (!list_empty(&priv->queue)) {
866 ipaq_write_gather(port);
867 spin_unlock_irqrestore(&write_list_lock, flags);
868 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
869 if (result)
870 dev_err(&port->dev,
871 "%s - failed submitting write urb, error %d\n",
872 __func__, result);
873 } else {
874 priv->active = 0;
875 spin_unlock_irqrestore(&write_list_lock, flags);
876 }
877
878 usb_serial_port_softint(port);
879}
880
881static int ipaq_write_room(struct tty_struct *tty)
882{
883 struct usb_serial_port *port = tty->driver_data;
884 struct ipaq_private *priv = usb_get_serial_port_data(port);
885
886 dbg("%s - freelen %d", __func__, priv->free_len);
887 return priv->free_len;
888}
889
890static int ipaq_chars_in_buffer(struct tty_struct *tty)
891{
892 struct usb_serial_port *port = tty->driver_data;
893 struct ipaq_private *priv = usb_get_serial_port_data(port);
894
895 dbg("%s - queuelen %d", __func__, priv->queue_len);
896 return priv->queue_len;
897}
898
899static void ipaq_destroy_lists(struct usb_serial_port *port)
900{
901 struct ipaq_private *priv = usb_get_serial_port_data(port);
902 struct ipaq_packet *pkt, *tmp;
903
904 list_for_each_entry_safe(pkt, tmp, &priv->queue, list) {
905 kfree(pkt->data);
906 kfree(pkt);
907 }
908 list_for_each_entry_safe(pkt, tmp, &priv->freelist, list) {
909 kfree(pkt->data);
910 kfree(pkt);
911 }
912}
913
914
915static int ipaq_calc_num_ports(struct usb_serial *serial) 604static int ipaq_calc_num_ports(struct usb_serial *serial)
916{ 605{
917 /* 606 /*
@@ -970,7 +659,6 @@ static int ipaq_startup(struct usb_serial *serial)
970static int __init ipaq_init(void) 659static int __init ipaq_init(void)
971{ 660{
972 int retval; 661 int retval;
973 spin_lock_init(&write_list_lock);
974 retval = usb_serial_register(&ipaq_device); 662 retval = usb_serial_register(&ipaq_device);
975 if (retval) 663 if (retval)
976 goto failed_usb_serial_register; 664 goto failed_usb_serial_register;
@@ -991,7 +679,6 @@ failed_usb_serial_register:
991 return retval; 679 return retval;
992} 680}
993 681
994
995static void __exit ipaq_exit(void) 682static void __exit ipaq_exit(void)
996{ 683{
997 usb_deregister(&ipaq_driver); 684 usb_deregister(&ipaq_driver);
diff --git a/drivers/usb/serial/ipaq.h b/drivers/usb/serial/ipaq.h
deleted file mode 100644
index 2b9035918b85..000000000000
--- a/drivers/usb/serial/ipaq.h
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * USB Compaq iPAQ driver
3 *
4 * Copyright (C) 2001 - 2002
5 * Ganesh Varadarajan <ganesh@veritas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
14#ifndef __LINUX_USB_SERIAL_IPAQ_H
15#define __LINUX_USB_SERIAL_IPAQ_H
16
17/*
18 * Since we can't queue our bulk write urbs (don't know why - it just
19 * doesn't work), we can send down only one write urb at a time. The simplistic
20 * approach taken by the generic usbserial driver will work, but it's not good
21 * for performance. Therefore, we buffer upto URBDATA_QUEUE_MAX bytes of write
22 * requests coming from the line discipline. This is done by chaining them
23 * in lists of struct ipaq_packet, each packet holding a maximum of
24 * PACKET_SIZE bytes.
25 *
26 * ipaq_write() can be called from bottom half context; hence we can't
27 * allocate memory for packets there. So we initialize a pool of packets at
28 * the first open and maintain a freelist.
29 *
30 * The value of PACKET_SIZE was empirically determined by
31 * checking the maximum write sizes sent down by the ppp ldisc.
32 * URBDATA_QUEUE_MAX is set to 64K, which is the maximum TCP window size.
33 */
34
35struct ipaq_packet {
36 char *data;
37 size_t len;
38 size_t written;
39 struct list_head list;
40};
41
42struct ipaq_private {
43 int active;
44 int queue_len;
45 int free_len;
46 struct list_head queue;
47 struct list_head freelist;
48};
49
50#define URBDATA_SIZE 4096
51#define URBDATA_QUEUE_MAX (64 * 1024)
52#define PACKET_SIZE 256
53
54#endif