static rwlock_t notifier_lock = RW_LOCK_UNLOCKED;
HLIST_HEAD(rx_dev_list);
-struct dev_rcv_lists rx_alldev_list;
+struct dev_rcv_lists *rx_alldev_list; /* shortcut to persistent entry */
static spinlock_t rcv_lists_lock = SPIN_LOCK_UNLOCKED;
static kmem_cache_t *rcv_cache;
if (!rcv_cache)
return -ENOMEM;
+ /* create a dev_rcv_list for unbound receiption */
+ if (!(rx_alldev_list = kmalloc(sizeof(*rx_alldev_list), GFP_KERNEL))) {
+ printk(KERN_ERR "CAN: allocation of rx_alldev_list failed\n");
+ return -ENOMEM;
+ }
+ memset(rx_alldev_list, 0, sizeof(*rx_alldev_list)); /* dev = NULL */
+
+ spin_lock(&rcv_lists_lock);
+ hlist_add_head_rcu(&rx_alldev_list->list, &rx_dev_list);
+ spin_unlock(&rcv_lists_lock);
+
if (stats_timer) {
/* statistics init */
init_timer(&stattimer);
unregister_netdevice_notifier(&can_netdev_notifier);
sock_unregister(PF_CAN);
+ /* TODO: remove rx_dev_list */
+
kmem_cache_destroy(rcv_cache);
}
if (!(d = find_dev_rcv_lists(dev))) {
DBG("receive list not found for dev %s, id %03X, mask %03X\n",
- dev->name, can_id, mask);
+ DNAME(dev), can_id, mask);
kmem_cache_free(rcv_cache, r);
ret = -ENODEV;
goto out_unlock;
if (!(d = find_dev_rcv_lists(dev))) {
DBG("receive list not found for dev %s, id %03X, mask %03X\n",
- dev->name, can_id, mask);
+ DNAME(dev), can_id, mask);
ret = -ENODEV;
goto out;
}
if (!next) {
DBG("receive list entry not found for "
- "dev %s, id %03X, mask %03X\n", dev->name, can_id, mask);
+ "dev %s, id %03X, mask %03X\n", DNAME(dev), can_id, mask);
ret = -EINVAL;
r = NULL;
goto out;
rcu_read_lock();
/* deliver the packet to sockets listening on all devices */
- matches = can_rcv_filter(&rx_alldev_list, skb);
+ matches = can_rcv_filter(rx_alldev_list, skb);
/* find receive list for this device */
if ((d = find_dev_rcv_lists(dev)))
/* find receive list for this device */
- if (!dev)
- return &rx_alldev_list;
-
/* The hlist_for_each_entry*() macros curse through the list
* using the pointer variable n and set d to the containing
* struct in each list iteration. Therefore, after list
" %-5s %03X %08x %08x %08x %8ld %s\n";
len += snprintf(page + len, PAGE_SIZE - len, fmt,
- dev->name, r->can_id, r->mask,
+ DNAME(dev), r->can_id, r->mask,
(unsigned int)r->func, (unsigned int)r->data,
r->matches, r->ident);
if (!hlist_empty(&d->rx_all)) {
len = can_print_recv_banner(page, len);
len = can_print_recv_list(page, len, &d->rx_all, d->dev);
- } else if (d->dev)
+ } else
len += snprintf(page + len, PAGE_SIZE - len,
- " (%s: no entry)\n", d->dev->name);
+ " (%s: no entry)\n", DNAME(d->dev));
}
rcu_read_unlock();
if (!hlist_empty(&d->rx_fil)) {
len = can_print_recv_banner(page, len);
len = can_print_recv_list(page, len, &d->rx_fil, d->dev);
- } else if (d->dev)
+ } else
len += snprintf(page + len, PAGE_SIZE - len,
- " (%s: no entry)\n", d->dev->name);
+ " (%s: no entry)\n", DNAME(d->dev));
}
rcu_read_unlock();
if (!hlist_empty(&d->rx_inv)) {
len = can_print_recv_banner(page, len);
len = can_print_recv_list(page, len, &d->rx_inv, d->dev);
- } else if (d->dev)
+ } else
len += snprintf(page + len, PAGE_SIZE - len,
- " (%s: no entry)\n", d->dev->name);
+ " (%s: no entry)\n", DNAME(d->dev));
}
rcu_read_unlock();
if (!hlist_empty(&d->rx_sff[i]) && len < PAGE_SIZE - 100)
len = can_print_recv_list(page, len, &d->rx_sff[i], d->dev);
}
- } else if (d->dev)
+ } else
len += snprintf(page + len, PAGE_SIZE - len,
- " (%s: no entry)\n", d->dev->name);
+ " (%s: no entry)\n", DNAME(d->dev));
}
rcu_read_unlock();
if (!hlist_empty(&d->rx_eff)) {
len = can_print_recv_banner(page, len);
len = can_print_recv_list(page, len, &d->rx_eff, d->dev);
- } else if (d->dev)
+ } else
len += snprintf(page + len, PAGE_SIZE - len,
- " (%s: no entry)\n", d->dev->name);
+ " (%s: no entry)\n", DNAME(d->dev));
}
rcu_read_unlock();
if (!hlist_empty(&d->rx_err)) {
len = can_print_recv_banner(page, len);
len = can_print_recv_list(page, len, &d->rx_err, d->dev);
- } else if (d->dev)
+ } else
len += snprintf(page + len, PAGE_SIZE - len,
- " (%s: no entry)\n", d->dev->name);
+ " (%s: no entry)\n", DNAME(d->dev));
}
rcu_read_unlock();