aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/atm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/atm')
-rw-r--r--drivers/usb/atm/cxacru.c4
-rw-r--r--drivers/usb/atm/speedtch.c82
-rw-r--r--drivers/usb/atm/ueagle-atm.c4
-rw-r--r--drivers/usb/atm/usbatm.c30
-rw-r--r--drivers/usb/atm/usbatm.h7
-rw-r--r--drivers/usb/atm/xusbatm.c4
6 files changed, 92 insertions, 39 deletions
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 675fdbd5967e..70a96e98152c 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -836,8 +836,8 @@ static struct usbatm_driver cxacru_driver = {
836 .heavy_init = cxacru_heavy_init, 836 .heavy_init = cxacru_heavy_init,
837 .unbind = cxacru_unbind, 837 .unbind = cxacru_unbind,
838 .atm_start = cxacru_atm_start, 838 .atm_start = cxacru_atm_start,
839 .in = CXACRU_EP_DATA, 839 .bulk_in = CXACRU_EP_DATA,
840 .out = CXACRU_EP_DATA, 840 .bulk_out = CXACRU_EP_DATA,
841 .rx_padding = 3, 841 .rx_padding = 3,
842 .tx_padding = 11, 842 .tx_padding = 11,
843}; 843};
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 0e981672f149..8c1c560cf051 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -35,6 +35,8 @@
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/stat.h> 36#include <linux/stat.h>
37#include <linux/timer.h> 37#include <linux/timer.h>
38#include <linux/types.h>
39#include <linux/usb_ch9.h>
38#include <linux/workqueue.h> 40#include <linux/workqueue.h>
39 41
40#include "usbatm.h" 42#include "usbatm.h"
@@ -66,24 +68,33 @@ static const char speedtch_driver_name[] = "speedtch";
66 68
67#define RESUBMIT_DELAY 1000 /* milliseconds */ 69#define RESUBMIT_DELAY 1000 /* milliseconds */
68 70
69#define DEFAULT_ALTSETTING 1 71#define DEFAULT_BULK_ALTSETTING 1
72#define DEFAULT_ISOC_ALTSETTING 2
70#define DEFAULT_DL_512_FIRST 0 73#define DEFAULT_DL_512_FIRST 0
74#define DEFAULT_ENABLE_ISOC 0
71#define DEFAULT_SW_BUFFERING 0 75#define DEFAULT_SW_BUFFERING 0
72 76
73static int altsetting = DEFAULT_ALTSETTING; 77static unsigned int altsetting = 0; /* zero means: use the default */
74static int dl_512_first = DEFAULT_DL_512_FIRST; 78static int dl_512_first = DEFAULT_DL_512_FIRST;
79static int enable_isoc = DEFAULT_ENABLE_ISOC;
75static int sw_buffering = DEFAULT_SW_BUFFERING; 80static int sw_buffering = DEFAULT_SW_BUFFERING;
76 81
77module_param(altsetting, int, S_IRUGO | S_IWUSR); 82module_param(altsetting, uint, S_IRUGO | S_IWUSR);
78MODULE_PARM_DESC(altsetting, 83MODULE_PARM_DESC(altsetting,
79 "Alternative setting for data interface (default: " 84 "Alternative setting for data interface (bulk_default: "
80 __MODULE_STRING(DEFAULT_ALTSETTING) ")"); 85 __MODULE_STRING(DEFAULT_BULK_ALTSETTING) "; isoc_default: "
86 __MODULE_STRING(DEFAULT_ISOC_ALTSETTING) ")");
81 87
82module_param(dl_512_first, bool, S_IRUGO | S_IWUSR); 88module_param(dl_512_first, bool, S_IRUGO | S_IWUSR);
83MODULE_PARM_DESC(dl_512_first, 89MODULE_PARM_DESC(dl_512_first,
84 "Read 512 bytes before sending firmware (default: " 90 "Read 512 bytes before sending firmware (default: "
85 __MODULE_STRING(DEFAULT_DL_512_FIRST) ")"); 91 __MODULE_STRING(DEFAULT_DL_512_FIRST) ")");
86 92
93module_param(enable_isoc, bool, S_IRUGO | S_IWUSR);
94MODULE_PARM_DESC(enable_isoc,
95 "Use isochronous transfers if available (default: "
96 __MODULE_STRING(DEFAULT_ENABLE_ISOC) ")");
97
87module_param(sw_buffering, bool, S_IRUGO | S_IWUSR); 98module_param(sw_buffering, bool, S_IRUGO | S_IWUSR);
88MODULE_PARM_DESC(sw_buffering, 99MODULE_PARM_DESC(sw_buffering,
89 "Enable software buffering (default: " 100 "Enable software buffering (default: "
@@ -91,7 +102,8 @@ MODULE_PARM_DESC(sw_buffering,
91 102
92#define INTERFACE_DATA 1 103#define INTERFACE_DATA 1
93#define ENDPOINT_INT 0x81 104#define ENDPOINT_INT 0x81
94#define ENDPOINT_DATA 0x07 105#define ENDPOINT_BULK_DATA 0x07
106#define ENDPOINT_ISOC_DATA 0x07
95#define ENDPOINT_FIRMWARE 0x05 107#define ENDPOINT_FIRMWARE 0x05
96 108
97#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) 109#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
@@ -687,11 +699,12 @@ static int speedtch_bind(struct usbatm_data *usbatm,
687 const struct usb_device_id *id) 699 const struct usb_device_id *id)
688{ 700{
689 struct usb_device *usb_dev = interface_to_usbdev(intf); 701 struct usb_device *usb_dev = interface_to_usbdev(intf);
690 struct usb_interface *cur_intf; 702 struct usb_interface *cur_intf, *data_intf;
691 struct speedtch_instance_data *instance; 703 struct speedtch_instance_data *instance;
692 int ifnum = intf->altsetting->desc.bInterfaceNumber; 704 int ifnum = intf->altsetting->desc.bInterfaceNumber;
693 int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; 705 int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces;
694 int i, ret; 706 int i, ret;
707 int use_isoc;
695 708
696 usb_dbg(usbatm, "%s entered\n", __func__); 709 usb_dbg(usbatm, "%s entered\n", __func__);
697 710
@@ -702,6 +715,11 @@ static int speedtch_bind(struct usbatm_data *usbatm,
702 return -ENODEV; 715 return -ENODEV;
703 } 716 }
704 717
718 if (!(data_intf = usb_ifnum_to_if(usb_dev, INTERFACE_DATA))) {
719 usb_err(usbatm, "%s: data interface not found!\n", __func__);
720 return -ENODEV;
721 }
722
705 /* claim all interfaces */ 723 /* claim all interfaces */
706 724
707 for (i=0; i < num_interfaces; i++) { 725 for (i=0; i < num_interfaces; i++) {
@@ -728,8 +746,9 @@ static int speedtch_bind(struct usbatm_data *usbatm,
728 746
729 instance->usbatm = usbatm; 747 instance->usbatm = usbatm;
730 748
731 /* altsetting may change at any moment, so take a snapshot */ 749 /* altsetting and enable_isoc may change at any moment, so take a snapshot */
732 instance->altsetting = altsetting; 750 instance->altsetting = altsetting;
751 use_isoc = enable_isoc;
733 752
734 if (instance->altsetting) 753 if (instance->altsetting)
735 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { 754 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) {
@@ -737,14 +756,44 @@ static int speedtch_bind(struct usbatm_data *usbatm,
737 instance->altsetting = 0; /* fall back to default */ 756 instance->altsetting = 0; /* fall back to default */
738 } 757 }
739 758
740 if (!instance->altsetting) { 759 if (!instance->altsetting && use_isoc)
741 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ALTSETTING)) < 0) { 760 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) {
742 usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ALTSETTING, ret); 761 usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret);
743 goto fail_free; 762 use_isoc = 0; /* fall back to bulk */
744 } 763 }
745 instance->altsetting = DEFAULT_ALTSETTING; 764
765 if (use_isoc) {
766 const struct usb_host_interface *desc = data_intf->cur_altsetting;
767 const __u8 target_address = USB_DIR_IN | usbatm->driver->isoc_in;
768 int i;
769
770 use_isoc = 0; /* fall back to bulk if endpoint not found */
771
772 for (i=0; i<desc->desc.bNumEndpoints; i++) {
773 const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc;
774
775 if ((endpoint_desc->bEndpointAddress == target_address)) {
776 use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
777 USB_ENDPOINT_XFER_ISOC;
778 break;
779 }
780 }
781
782 if (!use_isoc)
783 usb_info(usbatm, "isochronous transfer not supported - using bulk\n");
746 } 784 }
747 785
786 if (!use_isoc && !instance->altsetting)
787 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) {
788 usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret);
789 goto fail_free;
790 }
791
792 if (!instance->altsetting)
793 instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING;
794
795 usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0);
796
748 INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); 797 INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance);
749 798
750 instance->status_checker.timer.function = speedtch_status_poll; 799 instance->status_checker.timer.function = speedtch_status_poll;
@@ -771,7 +820,7 @@ static int speedtch_bind(struct usbatm_data *usbatm,
771 0x12, 0xc0, 0x07, 0x00, 820 0x12, 0xc0, 0x07, 0x00,
772 instance->scratch_buffer + OFFSET_7, SIZE_7, 500); 821 instance->scratch_buffer + OFFSET_7, SIZE_7, 500);
773 822
774 usbatm->flags = (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0); 823 usbatm->flags |= (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0);
775 824
776 usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not"); 825 usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not");
777 826
@@ -817,8 +866,9 @@ static struct usbatm_driver speedtch_usbatm_driver = {
817 .unbind = speedtch_unbind, 866 .unbind = speedtch_unbind,
818 .atm_start = speedtch_atm_start, 867 .atm_start = speedtch_atm_start,
819 .atm_stop = speedtch_atm_stop, 868 .atm_stop = speedtch_atm_stop,
820 .in = ENDPOINT_DATA, 869 .bulk_in = ENDPOINT_BULK_DATA,
821 .out = ENDPOINT_DATA 870 .bulk_out = ENDPOINT_BULK_DATA,
871 .isoc_in = ENDPOINT_ISOC_DATA
822}; 872};
823 873
824static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) 874static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index aa072ad953a6..956cd9e82dee 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -1705,8 +1705,8 @@ static struct usbatm_driver uea_usbatm_driver = {
1705 .atm_start = uea_atm_open, 1705 .atm_start = uea_atm_open,
1706 .unbind = uea_unbind, 1706 .unbind = uea_unbind,
1707 .heavy_init = uea_heavy, 1707 .heavy_init = uea_heavy,
1708 .in = UEA_BULK_DATA_PIPE, 1708 .bulk_in = UEA_BULK_DATA_PIPE,
1709 .out = UEA_BULK_DATA_PIPE, 1709 .bulk_out = UEA_BULK_DATA_PIPE,
1710}; 1710};
1711 1711
1712static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) 1712static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 1d829c29c86d..923f2d9269bc 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -1049,17 +1049,23 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1049 init_completion(&instance->thread_exited); 1049 init_completion(&instance->thread_exited);
1050 1050
1051 INIT_LIST_HEAD(&instance->vcc_list); 1051 INIT_LIST_HEAD(&instance->vcc_list);
1052 skb_queue_head_init(&instance->sndqueue);
1052 1053
1053 usbatm_init_channel(&instance->rx_channel); 1054 usbatm_init_channel(&instance->rx_channel);
1054 usbatm_init_channel(&instance->tx_channel); 1055 usbatm_init_channel(&instance->tx_channel);
1055 tasklet_init(&instance->rx_channel.tasklet, usbatm_rx_process, (unsigned long)instance); 1056 tasklet_init(&instance->rx_channel.tasklet, usbatm_rx_process, (unsigned long)instance);
1056 tasklet_init(&instance->tx_channel.tasklet, usbatm_tx_process, (unsigned long)instance); 1057 tasklet_init(&instance->tx_channel.tasklet, usbatm_tx_process, (unsigned long)instance);
1057 instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->in);
1058 instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out);
1059 instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding; 1058 instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding;
1060 instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding; 1059 instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding;
1061 instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance; 1060 instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance;
1062 1061
1062 if ((instance->flags & UDSL_USE_ISOC) && driver->isoc_in)
1063 instance->rx_channel.endpoint = usb_rcvisocpipe(usb_dev, driver->isoc_in);
1064 else
1065 instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->bulk_in);
1066
1067 instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->bulk_out);
1068
1063 /* tx buffer size must be a positive multiple of the stride */ 1069 /* tx buffer size must be a positive multiple of the stride */
1064 instance->tx_channel.buf_size = max (instance->tx_channel.stride, 1070 instance->tx_channel.buf_size = max (instance->tx_channel.stride,
1065 snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride)); 1071 snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride));
@@ -1080,6 +1086,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1080 num_packets--; 1086 num_packets--;
1081 1087
1082 instance->rx_channel.buf_size = num_packets * maxpacket; 1088 instance->rx_channel.buf_size = num_packets * maxpacket;
1089 instance->rx_channel.packet_size = maxpacket;
1083 1090
1084#ifdef DEBUG 1091#ifdef DEBUG
1085 for (i = 0; i < 2; i++) { 1092 for (i = 0; i < 2; i++) {
@@ -1090,22 +1097,16 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1090 } 1097 }
1091#endif 1098#endif
1092 1099
1093 skb_queue_head_init(&instance->sndqueue); 1100 /* initialize urbs */
1094 1101
1095 for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) { 1102 for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
1096 struct urb *urb;
1097 u8 *buffer; 1103 u8 *buffer;
1098 unsigned int iso_packets = 0, iso_size = 0;
1099 struct usbatm_channel *channel = i < num_rcv_urbs ? 1104 struct usbatm_channel *channel = i < num_rcv_urbs ?
1100 &instance->rx_channel : &instance->tx_channel; 1105 &instance->rx_channel : &instance->tx_channel;
1106 struct urb *urb;
1107 unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0;
1101 1108
1102 if (usb_pipeisoc(channel->endpoint)) { 1109 UDSL_ASSERT(!usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
1103 /* don't expect iso out endpoints */
1104 iso_size = usb_maxpacket(instance->usb_dev, channel->endpoint, 0);
1105 iso_size -= iso_size % channel->stride; /* alignment */
1106 BUG_ON(!iso_size);
1107 iso_packets = (channel->buf_size - 1) / iso_size + 1;
1108 }
1109 1110
1110 urb = usb_alloc_urb(iso_packets, GFP_KERNEL); 1111 urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
1111 if (!urb) { 1112 if (!urb) {
@@ -1132,9 +1133,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1132 urb->transfer_flags = URB_ISO_ASAP; 1133 urb->transfer_flags = URB_ISO_ASAP;
1133 urb->number_of_packets = iso_packets; 1134 urb->number_of_packets = iso_packets;
1134 for (j = 0; j < iso_packets; j++) { 1135 for (j = 0; j < iso_packets; j++) {
1135 urb->iso_frame_desc[j].offset = iso_size * j; 1136 urb->iso_frame_desc[j].offset = channel->packet_size * j;
1136 urb->iso_frame_desc[j].length = min_t(int, iso_size, 1137 urb->iso_frame_desc[j].length = channel->packet_size;
1137 channel->buf_size - urb->iso_frame_desc[j].offset);
1138 } 1138 }
1139 } 1139 }
1140 1140
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h
index 1a31cf87bb1f..0e2caa0967c1 100644
--- a/drivers/usb/atm/usbatm.h
+++ b/drivers/usb/atm/usbatm.h
@@ -87,6 +87,7 @@
87/* flags, set by mini-driver in bind() */ 87/* flags, set by mini-driver in bind() */
88 88
89#define UDSL_SKIP_HEAVY_INIT (1<<0) 89#define UDSL_SKIP_HEAVY_INIT (1<<0)
90#define UDSL_USE_ISOC (1<<1)
90 91
91 92
92/* mini driver */ 93/* mini driver */
@@ -118,8 +119,9 @@ struct usbatm_driver {
118 /* cleanup ATM device ... can sleep, but can't fail */ 119 /* cleanup ATM device ... can sleep, but can't fail */
119 void (*atm_stop) (struct usbatm_data *, struct atm_dev *); 120 void (*atm_stop) (struct usbatm_data *, struct atm_dev *);
120 121
121 int in; /* rx endpoint */ 122 int bulk_in; /* bulk rx endpoint */
122 int out; /* tx endpoint */ 123 int isoc_in; /* isochronous rx endpoint */
124 int bulk_out; /* bulk tx endpoint */
123 125
124 unsigned rx_padding; 126 unsigned rx_padding;
125 unsigned tx_padding; 127 unsigned tx_padding;
@@ -134,6 +136,7 @@ struct usbatm_channel {
134 int endpoint; /* usb pipe */ 136 int endpoint; /* usb pipe */
135 unsigned int stride; /* ATM cell size + padding */ 137 unsigned int stride; /* ATM cell size + padding */
136 unsigned int buf_size; /* urb buffer size */ 138 unsigned int buf_size; /* urb buffer size */
139 unsigned int packet_size; /* endpoint maxpacket */
137 spinlock_t lock; 140 spinlock_t lock;
138 struct list_head list; 141 struct list_head list;
139 struct tasklet_struct tasklet; 142 struct tasklet_struct tasklet;
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 83848ee2c6fe..42d6823b82b3 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -210,8 +210,8 @@ static int __init xusbatm_init(void)
210 xusbatm_drivers[i].bind = xusbatm_bind; 210 xusbatm_drivers[i].bind = xusbatm_bind;
211 xusbatm_drivers[i].unbind = xusbatm_unbind; 211 xusbatm_drivers[i].unbind = xusbatm_unbind;
212 xusbatm_drivers[i].atm_start = xusbatm_atm_start; 212 xusbatm_drivers[i].atm_start = xusbatm_atm_start;
213 xusbatm_drivers[i].in = rx_endpoint[i]; 213 xusbatm_drivers[i].bulk_in = rx_endpoint[i];
214 xusbatm_drivers[i].out = tx_endpoint[i]; 214 xusbatm_drivers[i].bulk_out = tx_endpoint[i];
215 xusbatm_drivers[i].rx_padding = rx_padding[i]; 215 xusbatm_drivers[i].rx_padding = rx_padding[i];
216 xusbatm_drivers[i].tx_padding = tx_padding[i]; 216 xusbatm_drivers[i].tx_padding = tx_padding[i];
217 } 217 }