diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-08 12:11:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-08 12:11:10 -0400 |
commit | 96b8eaa14a20771997b501a049e418b871bf9def (patch) | |
tree | 31d9724f7628fab85bbb0a08e694450770494e96 | |
parent | bed7a560333d40269a886c4421d4c8f964a32177 (diff) | |
parent | 0eb1bd210d94e9f2c87551d794bb2755e5e24eed (diff) |
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
-rw-r--r-- | drivers/base/class.c | 32 | ||||
-rw-r--r-- | drivers/net/irda/irda-usb.c | 2 | ||||
-rw-r--r-- | include/linux/device.h | 2 | ||||
-rw-r--r-- | include/linux/netdevice.h | 2 | ||||
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 49 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 2 |
7 files changed, 51 insertions, 40 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index 0e71dff327cd..b1ea4df85c7d 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd) | |||
456 | } | 456 | } |
457 | } | 457 | } |
458 | 458 | ||
459 | static int class_device_add_groups(struct class_device * cd) | ||
460 | { | ||
461 | int i; | ||
462 | int error = 0; | ||
463 | |||
464 | if (cd->groups) { | ||
465 | for (i = 0; cd->groups[i]; i++) { | ||
466 | error = sysfs_create_group(&cd->kobj, cd->groups[i]); | ||
467 | if (error) { | ||
468 | while (--i >= 0) | ||
469 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | ||
470 | goto out; | ||
471 | } | ||
472 | } | ||
473 | } | ||
474 | out: | ||
475 | return error; | ||
476 | } | ||
477 | |||
478 | static void class_device_remove_groups(struct class_device * cd) | ||
479 | { | ||
480 | int i; | ||
481 | if (cd->groups) { | ||
482 | for (i = 0; cd->groups[i]; i++) { | ||
483 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | ||
484 | } | ||
485 | } | ||
486 | } | ||
487 | |||
459 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | 488 | static ssize_t show_dev(struct class_device *class_dev, char *buf) |
460 | { | 489 | { |
461 | return print_dev_t(buf, class_dev->devt); | 490 | return print_dev_t(buf, class_dev->devt); |
@@ -559,6 +588,8 @@ int class_device_add(struct class_device *class_dev) | |||
559 | class_name); | 588 | class_name); |
560 | } | 589 | } |
561 | 590 | ||
591 | class_device_add_groups(class_dev); | ||
592 | |||
562 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); | 593 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); |
563 | 594 | ||
564 | /* notify any interfaces this device is now here */ | 595 | /* notify any interfaces this device is now here */ |
@@ -672,6 +703,7 @@ void class_device_del(struct class_device *class_dev) | |||
672 | if (class_dev->devt_attr) | 703 | if (class_dev->devt_attr) |
673 | class_device_remove_file(class_dev, class_dev->devt_attr); | 704 | class_device_remove_file(class_dev, class_dev->devt_attr); |
674 | class_device_remove_attrs(class_dev); | 705 | class_device_remove_attrs(class_dev); |
706 | class_device_remove_groups(class_dev); | ||
675 | 707 | ||
676 | kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); | 708 | kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); |
677 | kobject_del(&class_dev->kobj); | 709 | kobject_del(&class_dev->kobj); |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 96bdb73c2283..cd87593e4e8a 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
@@ -1778,7 +1778,7 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1778 | 1778 | ||
1779 | if (self->needspatch) { | 1779 | if (self->needspatch) { |
1780 | ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0), | 1780 | ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0), |
1781 | 0x02, 0x40, 0, 0, 0, 0, msecs_to_jiffies(500)); | 1781 | 0x02, 0x40, 0, 0, NULL, 0, 500); |
1782 | if (ret < 0) { | 1782 | if (ret < 0) { |
1783 | IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret); | 1783 | IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret); |
1784 | goto err_out_3; | 1784 | goto err_out_3; |
diff --git a/include/linux/device.h b/include/linux/device.h index f6e72a65a3f2..e8e53b9accc6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -200,6 +200,7 @@ extern int class_device_create_file(struct class_device *, | |||
200 | * @node: for internal use by the driver core only. | 200 | * @node: for internal use by the driver core only. |
201 | * @kobj: for internal use by the driver core only. | 201 | * @kobj: for internal use by the driver core only. |
202 | * @devt_attr: for internal use by the driver core only. | 202 | * @devt_attr: for internal use by the driver core only. |
203 | * @groups: optional additional groups to be created | ||
203 | * @dev: if set, a symlink to the struct device is created in the sysfs | 204 | * @dev: if set, a symlink to the struct device is created in the sysfs |
204 | * directory for this struct class device. | 205 | * directory for this struct class device. |
205 | * @class_data: pointer to whatever you want to store here for this struct | 206 | * @class_data: pointer to whatever you want to store here for this struct |
@@ -228,6 +229,7 @@ struct class_device { | |||
228 | struct device * dev; /* not necessary, but nice to have */ | 229 | struct device * dev; /* not necessary, but nice to have */ |
229 | void * class_data; /* class-specific data */ | 230 | void * class_data; /* class-specific data */ |
230 | struct class_device *parent; /* parent of this child device, if there is one */ | 231 | struct class_device *parent; /* parent of this child device, if there is one */ |
232 | struct attribute_group ** groups; /* optional groups */ | ||
231 | 233 | ||
232 | void (*release)(struct class_device *dev); | 234 | void (*release)(struct class_device *dev); |
233 | int (*uevent)(struct class_device *dev, char **envp, | 235 | int (*uevent)(struct class_device *dev, char **envp, |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 01db7b88a2b1..309f9190a922 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -506,6 +506,8 @@ struct net_device | |||
506 | 506 | ||
507 | /* class/net/name entry */ | 507 | /* class/net/name entry */ |
508 | struct class_device class_dev; | 508 | struct class_device class_dev; |
509 | /* space for optional statistics and wireless sysfs groups */ | ||
510 | struct attribute_group *sysfs_groups[3]; | ||
509 | }; | 511 | }; |
510 | 512 | ||
511 | #define NETDEV_ALIGN 32 | 513 | #define NETDEV_ALIGN 32 |
diff --git a/net/core/dev.c b/net/core/dev.c index 3bad1afc89fa..9ab3cfa58466 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3043,11 +3043,11 @@ void netdev_run_todo(void) | |||
3043 | 3043 | ||
3044 | switch(dev->reg_state) { | 3044 | switch(dev->reg_state) { |
3045 | case NETREG_REGISTERING: | 3045 | case NETREG_REGISTERING: |
3046 | dev->reg_state = NETREG_REGISTERED; | ||
3047 | err = netdev_register_sysfs(dev); | 3046 | err = netdev_register_sysfs(dev); |
3048 | if (err) | 3047 | if (err) |
3049 | printk(KERN_ERR "%s: failed sysfs registration (%d)\n", | 3048 | printk(KERN_ERR "%s: failed sysfs registration (%d)\n", |
3050 | dev->name, err); | 3049 | dev->name, err); |
3050 | dev->reg_state = NETREG_REGISTERED; | ||
3051 | break; | 3051 | break; |
3052 | 3052 | ||
3053 | case NETREG_UNREGISTERING: | 3053 | case NETREG_UNREGISTERING: |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index c12990c9c603..47a6fceb6771 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -29,7 +29,7 @@ static const char fmt_ulong[] = "%lu\n"; | |||
29 | 29 | ||
30 | static inline int dev_isalive(const struct net_device *dev) | 30 | static inline int dev_isalive(const struct net_device *dev) |
31 | { | 31 | { |
32 | return dev->reg_state == NETREG_REGISTERED; | 32 | return dev->reg_state <= NETREG_REGISTERED; |
33 | } | 33 | } |
34 | 34 | ||
35 | /* use same locking rules as GIF* ioctl's */ | 35 | /* use same locking rules as GIF* ioctl's */ |
@@ -445,58 +445,33 @@ static struct class net_class = { | |||
445 | 445 | ||
446 | void netdev_unregister_sysfs(struct net_device * net) | 446 | void netdev_unregister_sysfs(struct net_device * net) |
447 | { | 447 | { |
448 | struct class_device * class_dev = &(net->class_dev); | 448 | class_device_del(&(net->class_dev)); |
449 | |||
450 | if (net->get_stats) | ||
451 | sysfs_remove_group(&class_dev->kobj, &netstat_group); | ||
452 | |||
453 | #ifdef WIRELESS_EXT | ||
454 | if (net->get_wireless_stats || (net->wireless_handlers && | ||
455 | net->wireless_handlers->get_wireless_stats)) | ||
456 | sysfs_remove_group(&class_dev->kobj, &wireless_group); | ||
457 | #endif | ||
458 | class_device_del(class_dev); | ||
459 | |||
460 | } | 449 | } |
461 | 450 | ||
462 | /* Create sysfs entries for network device. */ | 451 | /* Create sysfs entries for network device. */ |
463 | int netdev_register_sysfs(struct net_device *net) | 452 | int netdev_register_sysfs(struct net_device *net) |
464 | { | 453 | { |
465 | struct class_device *class_dev = &(net->class_dev); | 454 | struct class_device *class_dev = &(net->class_dev); |
466 | int ret; | 455 | struct attribute_group **groups = net->sysfs_groups; |
467 | 456 | ||
457 | class_device_initialize(class_dev); | ||
468 | class_dev->class = &net_class; | 458 | class_dev->class = &net_class; |
469 | class_dev->class_data = net; | 459 | class_dev->class_data = net; |
460 | class_dev->groups = groups; | ||
470 | 461 | ||
462 | BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ); | ||
471 | strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE); | 463 | strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE); |
472 | if ((ret = class_device_register(class_dev))) | ||
473 | goto out; | ||
474 | 464 | ||
475 | if (net->get_stats && | 465 | if (net->get_stats) |
476 | (ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) | 466 | *groups++ = &netstat_group; |
477 | goto out_unreg; | ||
478 | 467 | ||
479 | #ifdef WIRELESS_EXT | 468 | #ifdef WIRELESS_EXT |
480 | if (net->get_wireless_stats || (net->wireless_handlers && | 469 | if (net->get_wireless_stats |
481 | net->wireless_handlers->get_wireless_stats)) { | 470 | || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)) |
482 | ret = sysfs_create_group(&class_dev->kobj, &wireless_group); | 471 | *groups++ = &wireless_group; |
483 | if (ret) | ||
484 | goto out_cleanup; | ||
485 | } | ||
486 | return 0; | ||
487 | out_cleanup: | ||
488 | if (net->get_stats) | ||
489 | sysfs_remove_group(&class_dev->kobj, &netstat_group); | ||
490 | #else | ||
491 | return 0; | ||
492 | #endif | 472 | #endif |
493 | 473 | ||
494 | out_unreg: | 474 | return class_device_add(class_dev); |
495 | printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n", | ||
496 | net->name, ret); | ||
497 | class_device_unregister(class_dev); | ||
498 | out: | ||
499 | return ret; | ||
500 | } | 475 | } |
501 | 476 | ||
502 | int netdev_sysfs_init(void) | 477 | int netdev_sysfs_init(void) |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 18d7fad474d7..c9026dbf4c93 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -337,7 +337,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb) | |||
337 | * Initialise the virtual path cache for the packet. It describes | 337 | * Initialise the virtual path cache for the packet. It describes |
338 | * how the packet travels inside Linux networking. | 338 | * how the packet travels inside Linux networking. |
339 | */ | 339 | */ |
340 | if (likely(skb->dst == NULL)) { | 340 | if (skb->dst == NULL) { |
341 | int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, | 341 | int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, |
342 | skb->dev); | 342 | skb->dev); |
343 | if (unlikely(err)) { | 343 | if (unlikely(err)) { |