aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/atm/usbatm.c
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2006-01-13 04:59:23 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-31 20:23:40 -0500
commit80aae7a17afd21f7ba900dd566fb23a2444021f8 (patch)
tree2193fe416373daddbc2b1da8bca61664081b927b /drivers/usb/atm/usbatm.c
parent6f7494759870ec6fbb066f7202c5585fe36fbe82 (diff)
[PATCH] USBATM: allow isochronous transfer
While the usbatm core has had some support for using isoc urbs for some time, there was no way for users to turn it on. While use of isoc transfer should still be considered experimental, it now works well enough to let users turn it on. Minidrivers signal to the core that they want to use isoc transfer by setting the new UDSL_USE_ISOC flag. The speedtch minidriver gets a new module parameter enable_isoc (defaults to false), plus some logic that checks for the existence of an isoc receive endpoint (not all speedtouch modems have one). Signed-off-by: Duncan Sands <baldrick@free.fr> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/atm/usbatm.c')
-rw-r--r--drivers/usb/atm/usbatm.c30
1 files changed, 15 insertions, 15 deletions
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