Commit 6332c743 authored by Duncan Sands's avatar Duncan Sands Committed by Greg Kroah-Hartman

[PATCH] USB speedtouch: add module parameters

parent d9d1babe
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/timer.h> #include <linux/timer.h>
...@@ -102,12 +103,43 @@ static const char udsl_driver_name [] = "speedtch"; ...@@ -102,12 +103,43 @@ static const char udsl_driver_name [] = "speedtch";
#define SPEEDTOUCH_VENDORID 0x06b9 #define SPEEDTOUCH_VENDORID 0x06b9
#define SPEEDTOUCH_PRODUCTID 0x4061 #define SPEEDTOUCH_PRODUCTID 0x4061
#define UDSL_NUM_RCV_URBS 1 #define UDSL_MAX_RCV_URBS 4
#define UDSL_NUM_SND_URBS 1 #define UDSL_MAX_SND_URBS 4
#define UDSL_NUM_RCV_BUFS (2*UDSL_NUM_RCV_URBS) #define UDSL_MAX_RCV_BUFS 8
#define UDSL_NUM_SND_BUFS (2*UDSL_NUM_SND_URBS) #define UDSL_MAX_SND_BUFS 8
#define UDSL_RCV_BUF_SIZE 32 /* ATM cells */ #define UDSL_MAX_RCV_BUF_SIZE 1024 /* ATM cells */
#define UDSL_SND_BUF_SIZE 64 /* ATM cells */ #define UDSL_MAX_SND_BUF_SIZE 1024 /* ATM cells */
#define UDSL_DEFAULT_RCV_URBS 1
#define UDSL_DEFAULT_SND_URBS 1
#define UDSL_DEFAULT_RCV_BUFS 2
#define UDSL_DEFAULT_SND_BUFS 2
#define UDSL_DEFAULT_RCV_BUF_SIZE 64 /* ATM cells */
#define UDSL_DEFAULT_SND_BUF_SIZE 64 /* ATM cells */
static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
static unsigned int num_rcv_bufs = UDSL_DEFAULT_RCV_BUFS;
static unsigned int num_snd_bufs = UDSL_DEFAULT_SND_BUFS;
static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE;
static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE;
module_param (num_rcv_urbs, uint, 0444);
MODULE_PARM_DESC (num_rcv_urbs, "Number of urbs used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_URBS) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_URBS) ")");
module_param (num_snd_urbs, uint, 0444);
MODULE_PARM_DESC (num_snd_urbs, "Number of urbs used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_URBS) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_URBS) ")");
module_param (num_rcv_bufs, uint, 0444);
MODULE_PARM_DESC (num_rcv_bufs, "Number of buffers used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_BUFS) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_BUFS) ")");
module_param (num_snd_bufs, uint, 0444);
MODULE_PARM_DESC (num_snd_bufs, "Number of buffers used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_BUFS) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_BUFS) ")");
module_param (rcv_buf_size, uint, 0444);
MODULE_PARM_DESC (rcv_buf_size, "Size of the buffers used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_BUF_SIZE) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_BUF_SIZE) ")");
module_param (snd_buf_size, uint, 0444);
MODULE_PARM_DESC (snd_buf_size, "Size of the buffers used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_BUF_SIZE) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_BUF_SIZE) ")");
#define UDSL_IOCTL_LINE_UP 1 #define UDSL_IOCTL_LINE_UP 1
#define UDSL_IOCTL_LINE_DOWN 2 #define UDSL_IOCTL_LINE_DOWN 2
...@@ -196,8 +228,8 @@ struct udsl_instance_data { ...@@ -196,8 +228,8 @@ struct udsl_instance_data {
struct list_head vcc_list; struct list_head vcc_list;
/* receive */ /* receive */
struct udsl_receiver receivers [UDSL_NUM_RCV_URBS]; struct udsl_receiver receivers [UDSL_MAX_RCV_URBS];
struct udsl_receive_buffer receive_buffers [UDSL_NUM_RCV_BUFS]; struct udsl_receive_buffer receive_buffers [UDSL_MAX_RCV_BUFS];
spinlock_t receive_lock; spinlock_t receive_lock;
struct list_head spare_receivers; struct list_head spare_receivers;
...@@ -207,8 +239,8 @@ struct udsl_instance_data { ...@@ -207,8 +239,8 @@ struct udsl_instance_data {
struct list_head spare_receive_buffers; struct list_head spare_receive_buffers;
/* send */ /* send */
struct udsl_sender senders [UDSL_NUM_SND_URBS]; struct udsl_sender senders [UDSL_MAX_SND_URBS];
struct udsl_send_buffer send_buffers [UDSL_NUM_SND_BUFS]; struct udsl_send_buffer send_buffers [UDSL_MAX_SND_BUFS];
struct sk_buff_head sndqueue; struct sk_buff_head sndqueue;
...@@ -503,7 +535,7 @@ static void udsl_complete_receive (struct urb *urb, struct pt_regs *regs) ...@@ -503,7 +535,7 @@ static void udsl_complete_receive (struct urb *urb, struct pt_regs *regs)
vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf); vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
BUG_ON (buf->filled_cells > UDSL_RCV_BUF_SIZE); BUG_ON (buf->filled_cells > rcv_buf_size);
/* may not be in_interrupt() */ /* may not be in_interrupt() */
spin_lock_irqsave (&instance->receive_lock, flags); spin_lock_irqsave (&instance->receive_lock, flags);
...@@ -541,7 +573,7 @@ static void udsl_process_receive (unsigned long data) ...@@ -541,7 +573,7 @@ static void udsl_process_receive (unsigned long data)
instance->usb_dev, instance->usb_dev,
usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
buf->base, buf->base,
UDSL_RCV_BUF_SIZE * ATM_CELL_SIZE, rcv_buf_size * ATM_CELL_SIZE,
udsl_complete_receive, udsl_complete_receive,
rcv); rcv);
...@@ -626,11 +658,11 @@ static void udsl_process_send (unsigned long data) ...@@ -626,11 +658,11 @@ static void udsl_process_send (unsigned long data)
instance->usb_dev, instance->usb_dev,
usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
buf->base, buf->base,
(UDSL_SND_BUF_SIZE - buf->free_cells) * ATM_CELL_SIZE, (snd_buf_size - buf->free_cells) * ATM_CELL_SIZE,
udsl_complete_send, udsl_complete_send,
snd); snd);
vdbg ("udsl_process_send: submitting urb 0x%p (%d cells), snd 0x%p, buf 0x%p", snd->urb, UDSL_SND_BUF_SIZE - buf->free_cells, snd, buf); vdbg ("udsl_process_send: submitting urb 0x%p (%d cells), snd 0x%p, buf 0x%p", snd->urb, snd_buf_size - buf->free_cells, snd, buf);
if ((err = usb_submit_urb(snd->urb, GFP_ATOMIC)) < 0) { if ((err = usb_submit_urb(snd->urb, GFP_ATOMIC)) < 0) {
dbg ("udsl_process_send: urb submission failed (%d)!", err); dbg ("udsl_process_send: urb submission failed (%d)!", err);
...@@ -662,7 +694,7 @@ static void udsl_process_send (unsigned long data) ...@@ -662,7 +694,7 @@ static void udsl_process_send (unsigned long data)
spin_unlock_irq (&instance->send_lock); spin_unlock_irq (&instance->send_lock);
buf->free_start = buf->base; buf->free_start = buf->base;
buf->free_cells = UDSL_SND_BUF_SIZE; buf->free_cells = snd_buf_size;
instance->current_buffer = buf; instance->current_buffer = buf;
} }
...@@ -676,7 +708,7 @@ static void udsl_process_send (unsigned long data) ...@@ -676,7 +708,7 @@ static void udsl_process_send (unsigned long data)
instance->current_buffer = NULL; instance->current_buffer = NULL;
} }
vdbg ("udsl_process_send: buffer contains %d cells, %d left", UDSL_SND_BUF_SIZE - buf->free_cells, buf->free_cells); vdbg ("udsl_process_send: buffer contains %d cells, %d left", snd_buf_size - buf->free_cells, buf->free_cells);
if (!UDSL_SKB (skb)->num_cells) { if (!UDSL_SKB (skb)->num_cells) {
struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc; struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc;
...@@ -1039,7 +1071,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -1039,7 +1071,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
INIT_LIST_HEAD (&instance->filled_send_buffers); INIT_LIST_HEAD (&instance->filled_send_buffers);
/* receive init */ /* receive init */
for (i = 0; i < UDSL_NUM_RCV_URBS; i++) { for (i = 0; i < num_rcv_urbs; i++) {
struct udsl_receiver *rcv = &(instance->receivers [i]); struct udsl_receiver *rcv = &(instance->receivers [i]);
if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) { if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) {
...@@ -1052,10 +1084,10 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -1052,10 +1084,10 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
list_add (&rcv->list, &instance->spare_receivers); list_add (&rcv->list, &instance->spare_receivers);
} }
for (i = 0; i < UDSL_NUM_RCV_BUFS; i++) { for (i = 0; i < num_rcv_bufs; i++) {
struct udsl_receive_buffer *buf = &(instance->receive_buffers [i]); struct udsl_receive_buffer *buf = &(instance->receive_buffers [i]);
if (!(buf->base = kmalloc (UDSL_RCV_BUF_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) { if (!(buf->base = kmalloc (rcv_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {
dbg ("udsl_usb_probe: no memory for receive buffer %d!", i); dbg ("udsl_usb_probe: no memory for receive buffer %d!", i);
goto fail; goto fail;
} }
...@@ -1064,7 +1096,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -1064,7 +1096,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
} }
/* send init */ /* send init */
for (i = 0; i < UDSL_NUM_SND_URBS; i++) { for (i = 0; i < num_snd_urbs; i++) {
struct udsl_sender *snd = &(instance->senders [i]); struct udsl_sender *snd = &(instance->senders [i]);
if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) { if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) {
...@@ -1077,10 +1109,10 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -1077,10 +1109,10 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
list_add (&snd->list, &instance->spare_senders); list_add (&snd->list, &instance->spare_senders);
} }
for (i = 0; i < UDSL_NUM_SND_BUFS; i++) { for (i = 0; i < num_snd_bufs; i++) {
struct udsl_send_buffer *buf = &(instance->send_buffers [i]); struct udsl_send_buffer *buf = &(instance->send_buffers [i]);
if (!(buf->base = kmalloc (UDSL_SND_BUF_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) { if (!(buf->base = kmalloc (snd_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {
dbg ("udsl_usb_probe: no memory for send buffer %d!", i); dbg ("udsl_usb_probe: no memory for send buffer %d!", i);
goto fail; goto fail;
} }
...@@ -1139,16 +1171,16 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -1139,16 +1171,16 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
return 0; return 0;
fail: fail:
for (i = 0; i < UDSL_NUM_SND_BUFS; i++) for (i = 0; i < num_snd_bufs; i++)
kfree (instance->send_buffers [i].base); kfree (instance->send_buffers [i].base);
for (i = 0; i < UDSL_NUM_SND_URBS; i++) for (i = 0; i < num_snd_urbs; i++)
usb_free_urb (instance->senders [i].urb); usb_free_urb (instance->senders [i].urb);
for (i = 0; i < UDSL_NUM_RCV_BUFS; i++) for (i = 0; i < num_rcv_bufs; i++)
kfree (instance->receive_buffers [i].base); kfree (instance->receive_buffers [i].base);
for (i = 0; i < UDSL_NUM_RCV_URBS; i++) for (i = 0; i < num_rcv_urbs; i++)
usb_free_urb (instance->receivers [i].urb); usb_free_urb (instance->receivers [i].urb);
kfree (instance); kfree (instance);
...@@ -1175,7 +1207,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1175,7 +1207,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
/* receive finalize */ /* receive finalize */
tasklet_disable (&instance->receive_tasklet); tasklet_disable (&instance->receive_tasklet);
for (i = 0; i < UDSL_NUM_RCV_URBS; i++) for (i = 0; i < num_rcv_urbs; i++)
if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0) if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result); dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
...@@ -1184,13 +1216,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1184,13 +1216,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
count = 0; count = 0;
spin_lock_irq (&instance->receive_lock); spin_lock_irq (&instance->receive_lock);
list_for_each (pos, &instance->spare_receivers) list_for_each (pos, &instance->spare_receivers)
if (++count > UDSL_NUM_RCV_URBS) if (++count > num_rcv_urbs)
panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__); panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
spin_unlock_irq (&instance->receive_lock); spin_unlock_irq (&instance->receive_lock);
dbg ("udsl_usb_disconnect: found %u spare receivers", count); dbg ("udsl_usb_disconnect: found %u spare receivers", count);
if (count == UDSL_NUM_RCV_URBS) if (count == num_rcv_urbs)
break; break;
set_current_state (TASK_RUNNING); set_current_state (TASK_RUNNING);
...@@ -1203,16 +1235,16 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1203,16 +1235,16 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
tasklet_enable (&instance->receive_tasklet); tasklet_enable (&instance->receive_tasklet);
for (i = 0; i < UDSL_NUM_RCV_URBS; i++) for (i = 0; i < num_rcv_urbs; i++)
usb_free_urb (instance->receivers [i].urb); usb_free_urb (instance->receivers [i].urb);
for (i = 0; i < UDSL_NUM_RCV_BUFS; i++) for (i = 0; i < num_rcv_bufs; i++)
kfree (instance->receive_buffers [i].base); kfree (instance->receive_buffers [i].base);
/* send finalize */ /* send finalize */
tasklet_disable (&instance->send_tasklet); tasklet_disable (&instance->send_tasklet);
for (i = 0; i < UDSL_NUM_SND_URBS; i++) for (i = 0; i < num_snd_urbs; i++)
if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0) if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result); dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
...@@ -1221,13 +1253,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1221,13 +1253,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
count = 0; count = 0;
spin_lock_irq (&instance->send_lock); spin_lock_irq (&instance->send_lock);
list_for_each (pos, &instance->spare_senders) list_for_each (pos, &instance->spare_senders)
if (++count > UDSL_NUM_SND_URBS) if (++count > num_snd_urbs)
panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__); panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
spin_unlock_irq (&instance->send_lock); spin_unlock_irq (&instance->send_lock);
dbg ("udsl_usb_disconnect: found %u spare senders", count); dbg ("udsl_usb_disconnect: found %u spare senders", count);
if (count == UDSL_NUM_SND_URBS) if (count == num_snd_urbs)
break; break;
set_current_state (TASK_RUNNING); set_current_state (TASK_RUNNING);
...@@ -1241,10 +1273,10 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1241,10 +1273,10 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
tasklet_enable (&instance->send_tasklet); tasklet_enable (&instance->send_tasklet);
for (i = 0; i < UDSL_NUM_SND_URBS; i++) for (i = 0; i < num_snd_urbs; i++)
usb_free_urb (instance->senders [i].urb); usb_free_urb (instance->senders [i].urb);
for (i = 0; i < UDSL_NUM_SND_BUFS; i++) for (i = 0; i < num_snd_bufs; i++)
kfree (instance->send_buffers [i].base); kfree (instance->send_buffers [i].base);
wmb (); wmb ();
...@@ -1270,6 +1302,11 @@ static int __init udsl_usb_init (void) ...@@ -1270,6 +1302,11 @@ static int __init udsl_usb_init (void)
return -EIO; return -EIO;
} }
if ((num_rcv_urbs > UDSL_MAX_RCV_URBS) || (num_snd_urbs > UDSL_MAX_SND_URBS) ||
(num_rcv_bufs > UDSL_MAX_RCV_BUFS) || (num_snd_bufs > UDSL_MAX_SND_BUFS) ||
(rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE) || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE))
return -EINVAL;
return usb_register (&udsl_usb_driver); return usb_register (&udsl_usb_driver);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment