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
This commit is contained in:
@@ -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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
|
|
||||||
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 *,
|
|||||||
* @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 {
|
|||||||
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
|
|||||||
|
|
||||||
/* 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)
|
|||||||
|
|
||||||
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";
|
|||||||
|
|
||||||
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 = {
|
|||||||
|
|
||||||
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)
|
|||||||
* 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)) {
|
||||||
|
Reference in New Issue
Block a user