#include <linux/kernel.h> /* for barrier */
#include <linux/module.h>
#include <linux/bitops.h>
+#include <linux/delay.h>
#include <net/sock.h> /* for struct sock */
#include "common.h"
LIST_HEAD(atm_devs);
-spinlock_t atm_dev_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(atm_dev_lock);
static struct atm_dev *__alloc_atm_dev(const char *type)
{
dev->signal = ATM_PHY_SIG_UNKNOWN;
dev->link_rate = ATM_OC3_PCR;
spin_lock_init(&dev->lock);
+ INIT_LIST_HEAD(&dev->local);
return dev;
}
warning_time = jiffies;
while (atomic_read(&dev->refcnt) != 1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ / 4);
+ msleep(250);
if ((jiffies - warning_time) > 10 * HZ) {
printk(KERN_EMERG "atm_dev_deregister: waiting for "
"dev %d to become free. Usage count = %d\n",
}
-static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats *arg, int zero)
+static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats __user *arg, int zero)
{
struct atm_dev_stats tmp;
int error = 0;
}
-int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
+int atm_dev_ioctl(unsigned int cmd, void __user *arg)
{
- void *buf;
+ void __user *buf;
int error, len, number, size = 0;
struct atm_dev *dev;
struct list_head *p;
int *tmp_buf, *tmp_p;
-
+ struct atm_iobuf __user *iobuf = arg;
+ struct atmif_sioc __user *sioc = arg;
switch (cmd) {
case ATM_GETNAMES:
- if (get_user(buf, &((struct atm_iobuf *) arg)->buffer))
+ if (get_user(buf, &iobuf->buffer))
return -EFAULT;
- if (get_user(len, &((struct atm_iobuf *) arg)->length))
+ if (get_user(len, &iobuf->length))
return -EFAULT;
spin_lock(&atm_dev_lock);
list_for_each(p, &atm_devs)
}
spin_unlock(&atm_dev_lock);
error = ((copy_to_user(buf, tmp_buf, size)) ||
- put_user(size, &((struct atm_iobuf *) arg)->length))
+ put_user(size, &iobuf->length))
? -EFAULT : 0;
kfree(tmp_buf);
return error;
break;
}
- if (get_user(buf, &((struct atmif_sioc *) arg)->arg))
+ if (get_user(buf, &sioc->arg))
return -EFAULT;
- if (get_user(len, &((struct atmif_sioc *) arg)->length))
+ if (get_user(len, &sioc->length))
return -EFAULT;
- if (get_user(number, &((struct atmif_sioc *) arg)->number))
+ if (get_user(number, &sioc->number))
return -EFAULT;
if (!(dev = atm_dev_lookup(number)))
size = error;
/* may return 0, but later on size == 0 means "don't
write the length" */
- error = put_user(size, &((struct atmif_sioc *) arg)->length)
+ error = put_user(size, &sioc->length)
? -EFAULT : 0;
goto done;
case ATM_SETLOOP:
- if (__ATM_LM_XTRMT((int) (long) buf) &&
- __ATM_LM_XTLOC((int) (long) buf) >
- __ATM_LM_XTRMT((int) (long) buf)) {
+ if (__ATM_LM_XTRMT((int) (unsigned long) buf) &&
+ __ATM_LM_XTLOC((int) (unsigned long) buf) >
+ __ATM_LM_XTRMT((int) (unsigned long) buf)) {
error = -EINVAL;
goto done;
}
}
if (size)
- error = put_user(size, &((struct atmif_sioc *) arg)->length)
+ error = put_user(size, &sioc->length)
? -EFAULT : 0;
else
error = 0;