Commit 96b8eaa1 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [IRDA] irda-usb: use NULL instead of 0
  [IPV4]: Remove likely in ip_rcv_finish()
  [NET]: Create netdev attribute_groups with class_device_add
  [CLASS DEVICE]: add attribute_group creation
parents bed7a560 0eb1bd21
...@@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd) ...@@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd)
} }
} }
static int class_device_add_groups(struct class_device * cd)
{
int i;
int error = 0;
if (cd->groups) {
for (i = 0; cd->groups[i]; i++) {
error = sysfs_create_group(&cd->kobj, cd->groups[i]);
if (error) {
while (--i >= 0)
sysfs_remove_group(&cd->kobj, cd->groups[i]);
goto out;
}
}
}
out:
return error;
}
static void class_device_remove_groups(struct class_device * cd)
{
int i;
if (cd->groups) {
for (i = 0; cd->groups[i]; i++) {
sysfs_remove_group(&cd->kobj, cd->groups[i]);
}
}
}
static ssize_t show_dev(struct class_device *class_dev, char *buf) static ssize_t show_dev(struct class_device *class_dev, char *buf)
{ {
return print_dev_t(buf, class_dev->devt); return print_dev_t(buf, class_dev->devt);
...@@ -559,6 +588,8 @@ int class_device_add(struct class_device *class_dev) ...@@ -559,6 +588,8 @@ int class_device_add(struct class_device *class_dev)
class_name); class_name);
} }
class_device_add_groups(class_dev);
kobject_uevent(&class_dev->kobj, KOBJ_ADD); kobject_uevent(&class_dev->kobj, KOBJ_ADD);
/* notify any interfaces this device is now here */ /* notify any interfaces this device is now here */
...@@ -672,6 +703,7 @@ void class_device_del(struct class_device *class_dev) ...@@ -672,6 +703,7 @@ void class_device_del(struct class_device *class_dev)
if (class_dev->devt_attr) if (class_dev->devt_attr)
class_device_remove_file(class_dev, class_dev->devt_attr); class_device_remove_file(class_dev, class_dev->devt_attr);
class_device_remove_attrs(class_dev); class_device_remove_attrs(class_dev);
class_device_remove_groups(class_dev);
kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
kobject_del(&class_dev->kobj); kobject_del(&class_dev->kobj);
......
...@@ -1778,7 +1778,7 @@ static int irda_usb_probe(struct usb_interface *intf, ...@@ -1778,7 +1778,7 @@ static int irda_usb_probe(struct usb_interface *intf,
if (self->needspatch) { if (self->needspatch) {
ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0), ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0),
0x02, 0x40, 0, 0, 0, 0, msecs_to_jiffies(500)); 0x02, 0x40, 0, 0, NULL, 0, 500);
if (ret < 0) { if (ret < 0) {
IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret); IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret);
goto err_out_3; goto err_out_3;
......
...@@ -200,6 +200,7 @@ extern int class_device_create_file(struct class_device *, ...@@ -200,6 +200,7 @@ extern int class_device_create_file(struct class_device *,
* @node: for internal use by the driver core only. * @node: for internal use by the driver core only.
* @kobj: for internal use by the driver core only. * @kobj: for internal use by the driver core only.
* @devt_attr: for internal use by the driver core only. * @devt_attr: for internal use by the driver core only.
* @groups: optional additional groups to be created
* @dev: if set, a symlink to the struct device is created in the sysfs * @dev: if set, a symlink to the struct device is created in the sysfs
* directory for this struct class device. * directory for this struct class device.
* @class_data: pointer to whatever you want to store here for this struct * @class_data: pointer to whatever you want to store here for this struct
...@@ -228,6 +229,7 @@ struct class_device { ...@@ -228,6 +229,7 @@ struct class_device {
struct device * dev; /* not necessary, but nice to have */ struct device * dev; /* not necessary, but nice to have */
void * class_data; /* class-specific data */ void * class_data; /* class-specific data */
struct class_device *parent; /* parent of this child device, if there is one */ struct class_device *parent; /* parent of this child device, if there is one */
struct attribute_group ** groups; /* optional groups */
void (*release)(struct class_device *dev); void (*release)(struct class_device *dev);
int (*uevent)(struct class_device *dev, char **envp, int (*uevent)(struct class_device *dev, char **envp,
......
...@@ -506,6 +506,8 @@ struct net_device ...@@ -506,6 +506,8 @@ struct net_device
/* class/net/name entry */ /* class/net/name entry */
struct class_device class_dev; struct class_device class_dev;
/* space for optional statistics and wireless sysfs groups */
struct attribute_group *sysfs_groups[3];
}; };
#define NETDEV_ALIGN 32 #define NETDEV_ALIGN 32
......
...@@ -3043,11 +3043,11 @@ void netdev_run_todo(void) ...@@ -3043,11 +3043,11 @@ void netdev_run_todo(void)
switch(dev->reg_state) { switch(dev->reg_state) {
case NETREG_REGISTERING: case NETREG_REGISTERING:
dev->reg_state = NETREG_REGISTERED;
err = netdev_register_sysfs(dev); err = netdev_register_sysfs(dev);
if (err) if (err)
printk(KERN_ERR "%s: failed sysfs registration (%d)\n", printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
dev->name, err); dev->name, err);
dev->reg_state = NETREG_REGISTERED;
break; break;
case NETREG_UNREGISTERING: case NETREG_UNREGISTERING:
......
...@@ -29,7 +29,7 @@ static const char fmt_ulong[] = "%lu\n"; ...@@ -29,7 +29,7 @@ static const char fmt_ulong[] = "%lu\n";
static inline int dev_isalive(const struct net_device *dev) static inline int dev_isalive(const struct net_device *dev)
{ {
return dev->reg_state == NETREG_REGISTERED; return dev->reg_state <= NETREG_REGISTERED;
} }
/* use same locking rules as GIF* ioctl's */ /* use same locking rules as GIF* ioctl's */
...@@ -445,58 +445,33 @@ static struct class net_class = { ...@@ -445,58 +445,33 @@ static struct class net_class = {
void netdev_unregister_sysfs(struct net_device * net) void netdev_unregister_sysfs(struct net_device * net)
{ {
struct class_device * class_dev = &(net->class_dev); class_device_del(&(net->class_dev));
if (net->get_stats)
sysfs_remove_group(&class_dev->kobj, &netstat_group);
#ifdef WIRELESS_EXT
if (net->get_wireless_stats || (net->wireless_handlers &&
net->wireless_handlers->get_wireless_stats))
sysfs_remove_group(&class_dev->kobj, &wireless_group);
#endif
class_device_del(class_dev);
} }
/* Create sysfs entries for network device. */ /* Create sysfs entries for network device. */
int netdev_register_sysfs(struct net_device *net) int netdev_register_sysfs(struct net_device *net)
{ {
struct class_device *class_dev = &(net->class_dev); struct class_device *class_dev = &(net->class_dev);
int ret; struct attribute_group **groups = net->sysfs_groups;
class_device_initialize(class_dev);
class_dev->class = &net_class; class_dev->class = &net_class;
class_dev->class_data = net; class_dev->class_data = net;
class_dev->groups = groups;
BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE); strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE);
if ((ret = class_device_register(class_dev)))
goto out;
if (net->get_stats && if (net->get_stats)
(ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) *groups++ = &netstat_group;
goto out_unreg;
#ifdef WIRELESS_EXT #ifdef WIRELESS_EXT
if (net->get_wireless_stats || (net->wireless_handlers && if (net->get_wireless_stats
net->wireless_handlers->get_wireless_stats)) { || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats))
ret = sysfs_create_group(&class_dev->kobj, &wireless_group); *groups++ = &wireless_group;
if (ret)
goto out_cleanup;
}
return 0;
out_cleanup:
if (net->get_stats)
sysfs_remove_group(&class_dev->kobj, &netstat_group);
#else
return 0;
#endif #endif
out_unreg: return class_device_add(class_dev);
printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
net->name, ret);
class_device_unregister(class_dev);
out:
return ret;
} }
int netdev_sysfs_init(void) int netdev_sysfs_init(void)
......
...@@ -337,7 +337,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb) ...@@ -337,7 +337,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
* Initialise the virtual path cache for the packet. It describes * Initialise the virtual path cache for the packet. It describes
* how the packet travels inside Linux networking. * how the packet travels inside Linux networking.
*/ */
if (likely(skb->dst == NULL)) { if (skb->dst == NULL) {
int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
skb->dev); skb->dev);
if (unlikely(err)) { if (unlikely(err)) {
......
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