aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/atm/usbatm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/atm/usbatm.c')
-rw-r--r--drivers/usb/atm/usbatm.c90
1 files changed, 59 insertions, 31 deletions
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 98b74b9dcdd2..1d829c29c86d 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -99,12 +99,11 @@ static const char usbatm_driver_name[] = "usbatm";
99 99
100#define UDSL_MAX_RCV_URBS 16 100#define UDSL_MAX_RCV_URBS 16
101#define UDSL_MAX_SND_URBS 16 101#define UDSL_MAX_SND_URBS 16
102#define UDSL_MAX_RCV_BUF_SIZE 1024 /* ATM cells */ 102#define UDSL_MAX_BUF_SIZE 64 * 1024 /* bytes */
103#define UDSL_MAX_SND_BUF_SIZE 1024 /* ATM cells */
104#define UDSL_DEFAULT_RCV_URBS 4 103#define UDSL_DEFAULT_RCV_URBS 4
105#define UDSL_DEFAULT_SND_URBS 4 104#define UDSL_DEFAULT_SND_URBS 4
106#define UDSL_DEFAULT_RCV_BUF_SIZE 64 /* ATM cells */ 105#define UDSL_DEFAULT_RCV_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */
107#define UDSL_DEFAULT_SND_BUF_SIZE 64 /* ATM cells */ 106#define UDSL_DEFAULT_SND_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */
108 107
109#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD) 108#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
110 109
@@ -112,8 +111,8 @@ static const char usbatm_driver_name[] = "usbatm";
112 111
113static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS; 112static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
114static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS; 113static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
115static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE; 114static unsigned int rcv_buf_bytes = UDSL_DEFAULT_RCV_BUF_SIZE;
116static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE; 115static unsigned int snd_buf_bytes = UDSL_DEFAULT_SND_BUF_SIZE;
117 116
118module_param(num_rcv_urbs, uint, S_IRUGO); 117module_param(num_rcv_urbs, uint, S_IRUGO);
119MODULE_PARM_DESC(num_rcv_urbs, 118MODULE_PARM_DESC(num_rcv_urbs,
@@ -127,15 +126,15 @@ MODULE_PARM_DESC(num_snd_urbs,
127 __MODULE_STRING(UDSL_MAX_SND_URBS) ", default: " 126 __MODULE_STRING(UDSL_MAX_SND_URBS) ", default: "
128 __MODULE_STRING(UDSL_DEFAULT_SND_URBS) ")"); 127 __MODULE_STRING(UDSL_DEFAULT_SND_URBS) ")");
129 128
130module_param(rcv_buf_size, uint, S_IRUGO); 129module_param(rcv_buf_bytes, uint, S_IRUGO);
131MODULE_PARM_DESC(rcv_buf_size, 130MODULE_PARM_DESC(rcv_buf_bytes,
132 "Size of the buffers used for reception in ATM cells (range: 1-" 131 "Size of the buffers used for reception, in bytes (range: 1-"
133 __MODULE_STRING(UDSL_MAX_RCV_BUF_SIZE) ", default: " 132 __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: "
134 __MODULE_STRING(UDSL_DEFAULT_RCV_BUF_SIZE) ")"); 133 __MODULE_STRING(UDSL_DEFAULT_RCV_BUF_SIZE) ")");
135 134
136module_param(snd_buf_size, uint, S_IRUGO); 135module_param(snd_buf_bytes, uint, S_IRUGO);
137MODULE_PARM_DESC(snd_buf_size, 136MODULE_PARM_DESC(snd_buf_bytes,
138 "Size of the buffers used for transmission in ATM cells (range: 1-" 137 "Size of the buffers used for transmission, in bytes (range: 1-"
139 __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: " 138 __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: "
140 __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")"); 139 __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")");
141 140
@@ -430,14 +429,14 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance,
430{ 429{
431 struct usbatm_control *ctrl = UDSL_SKB(skb); 430 struct usbatm_control *ctrl = UDSL_SKB(skb);
432 struct atm_vcc *vcc = ctrl->atm.vcc; 431 struct atm_vcc *vcc = ctrl->atm.vcc;
433 unsigned int num_written; 432 unsigned int bytes_written;
434 unsigned int stride = instance->tx_channel.stride; 433 unsigned int stride = instance->tx_channel.stride;
435 434
436 vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space); 435 vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space);
437 UDSL_ASSERT(!(avail_space % stride)); 436 UDSL_ASSERT(!(avail_space % stride));
438 437
439 for (num_written = 0; num_written < avail_space && ctrl->len; 438 for (bytes_written = 0; bytes_written < avail_space && ctrl->len;
440 num_written += stride, target += stride) { 439 bytes_written += stride, target += stride) {
441 unsigned int data_len = min_t(unsigned int, skb->len, ATM_CELL_PAYLOAD); 440 unsigned int data_len = min_t(unsigned int, skb->len, ATM_CELL_PAYLOAD);
442 unsigned int left = ATM_CELL_PAYLOAD - data_len; 441 unsigned int left = ATM_CELL_PAYLOAD - data_len;
443 u8 *ptr = target; 442 u8 *ptr = target;
@@ -480,7 +479,7 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance,
480 ctrl->crc = crc32_be(ctrl->crc, ptr, left); 479 ctrl->crc = crc32_be(ctrl->crc, ptr, left);
481 } 480 }
482 481
483 return num_written; 482 return bytes_written;
484} 483}
485 484
486 485
@@ -524,7 +523,7 @@ static void usbatm_tx_process(unsigned long data)
524 struct sk_buff *skb = instance->current_skb; 523 struct sk_buff *skb = instance->current_skb;
525 struct urb *urb = NULL; 524 struct urb *urb = NULL;
526 const unsigned int buf_size = instance->tx_channel.buf_size; 525 const unsigned int buf_size = instance->tx_channel.buf_size;
527 unsigned int num_written = 0; 526 unsigned int bytes_written = 0;
528 u8 *buffer = NULL; 527 u8 *buffer = NULL;
529 528
530 if (!skb) 529 if (!skb)
@@ -536,16 +535,16 @@ static void usbatm_tx_process(unsigned long data)
536 if (!urb) 535 if (!urb)
537 break; /* no more senders */ 536 break; /* no more senders */
538 buffer = urb->transfer_buffer; 537 buffer = urb->transfer_buffer;
539 num_written = (urb->status == -EAGAIN) ? 538 bytes_written = (urb->status == -EAGAIN) ?
540 urb->transfer_buffer_length : 0; 539 urb->transfer_buffer_length : 0;
541 } 540 }
542 541
543 num_written += usbatm_write_cells(instance, skb, 542 bytes_written += usbatm_write_cells(instance, skb,
544 buffer + num_written, 543 buffer + bytes_written,
545 buf_size - num_written); 544 buf_size - bytes_written);
546 545
547 vdbg("%s: wrote %u bytes from skb 0x%p to urb 0x%p", 546 vdbg("%s: wrote %u bytes from skb 0x%p to urb 0x%p",
548 __func__, num_written, skb, urb); 547 __func__, bytes_written, skb, urb);
549 548
550 if (!UDSL_SKB(skb)->len) { 549 if (!UDSL_SKB(skb)->len) {
551 struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc; 550 struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc;
@@ -556,8 +555,8 @@ static void usbatm_tx_process(unsigned long data)
556 skb = skb_dequeue(&instance->sndqueue); 555 skb = skb_dequeue(&instance->sndqueue);
557 } 556 }
558 557
559 if (num_written == buf_size || (!skb && num_written)) { 558 if (bytes_written == buf_size || (!skb && bytes_written)) {
560 urb->transfer_buffer_length = num_written; 559 urb->transfer_buffer_length = bytes_written;
561 560
562 if (usbatm_submit_urb(urb)) 561 if (usbatm_submit_urb(urb))
563 break; 562 break;
@@ -990,6 +989,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
990 char *buf; 989 char *buf;
991 int error = -ENOMEM; 990 int error = -ENOMEM;
992 int i, length; 991 int i, length;
992 unsigned int maxpacket, num_packets;
993 993
994 dev_dbg(dev, "%s: trying driver %s with vendor=%04x, product=%04x, ifnum %2d\n", 994 dev_dbg(dev, "%s: trying driver %s with vendor=%04x, product=%04x, ifnum %2d\n",
995 __func__, driver->driver_name, 995 __func__, driver->driver_name,
@@ -1058,10 +1058,38 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1058 instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out); 1058 instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out);
1059 instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding; 1059 instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding;
1060 instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding; 1060 instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding;
1061 instance->rx_channel.buf_size = rcv_buf_size * instance->rx_channel.stride;
1062 instance->tx_channel.buf_size = snd_buf_size * instance->tx_channel.stride;
1063 instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance; 1061 instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance;
1064 1062
1063 /* tx buffer size must be a positive multiple of the stride */
1064 instance->tx_channel.buf_size = max (instance->tx_channel.stride,
1065 snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride));
1066
1067 /* rx buffer size must be a positive multiple of the endpoint maxpacket */
1068 maxpacket = usb_maxpacket(usb_dev, instance->rx_channel.endpoint, 0);
1069
1070 if ((maxpacket < 1) || (maxpacket > UDSL_MAX_BUF_SIZE)) {
1071 dev_err(dev, "%s: invalid endpoint %02x!\n", __func__,
1072 usb_pipeendpoint(instance->rx_channel.endpoint));
1073 error = -EINVAL;
1074 goto fail_unbind;
1075 }
1076
1077 num_packets = max (1U, (rcv_buf_bytes + maxpacket / 2) / maxpacket); /* round */
1078
1079 if (num_packets * maxpacket > UDSL_MAX_BUF_SIZE)
1080 num_packets--;
1081
1082 instance->rx_channel.buf_size = num_packets * maxpacket;
1083
1084#ifdef DEBUG
1085 for (i = 0; i < 2; i++) {
1086 struct usbatm_channel *channel = i ?
1087 &instance->tx_channel : &instance->rx_channel;
1088
1089 dev_dbg(dev, "%s: using %d byte buffer for %s channel 0x%p\n", __func__, channel->buf_size, i ? "tx" : "rx", channel);
1090 }
1091#endif
1092
1065 skb_queue_head_init(&instance->sndqueue); 1093 skb_queue_head_init(&instance->sndqueue);
1066 1094
1067 for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) { 1095 for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
@@ -1232,10 +1260,10 @@ static int __init usbatm_usb_init(void)
1232 1260
1233 if ((num_rcv_urbs > UDSL_MAX_RCV_URBS) 1261 if ((num_rcv_urbs > UDSL_MAX_RCV_URBS)
1234 || (num_snd_urbs > UDSL_MAX_SND_URBS) 1262 || (num_snd_urbs > UDSL_MAX_SND_URBS)
1235 || (rcv_buf_size < 1) 1263 || (rcv_buf_bytes < 1)
1236 || (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE) 1264 || (rcv_buf_bytes > UDSL_MAX_BUF_SIZE)
1237 || (snd_buf_size < 1) 1265 || (snd_buf_bytes < 1)
1238 || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE)) 1266 || (snd_buf_bytes > UDSL_MAX_BUF_SIZE))
1239 return -EINVAL; 1267 return -EINVAL;
1240 1268
1241 return 0; 1269 return 0;