compat-2.6.h: include generated config.h
[~tnikolova/compat/.git] / compat / compat-3.2.c
1 /*
2  * Copyright 2012  Luis R. Rodriguez <mcgrof@frijolero.org>
3  * Copyright (c) 2012 Mellanox Technologies. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Compatibility file for Linux wireless for kernels 3.2.
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/device.h>
14 #include <linux/ethtool.h>
15 #include <linux/rtnetlink.h>
16 #include <linux/llist.h>
17
18 int __netdev_printk(const char *level, const struct net_device *dev,
19                            struct va_format *vaf)
20 {
21         int r;
22
23         if (dev && dev->dev.parent)
24 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
25                 r = dev_printk(level, dev->dev.parent, "%s: %pV",
26                                netdev_name(dev), vaf);
27 #else
28                 /* XXX: this could likely be done better but I'm lazy */
29                 r = printk("%s%s: %pV", level, netdev_name(dev), vaf);
30 #endif
31         else if (dev)
32                 r = printk("%s%s: %pV", level, netdev_name(dev), vaf);
33         else
34                 r = printk("%s(NULL net_device): %pV", level, vaf);
35
36         return r;
37 }
38 EXPORT_SYMBOL_GPL(__netdev_printk);
39
40 int __ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
41 {
42         ASSERT_RTNL();
43
44         if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
45                 return -EOPNOTSUPP;
46
47         memset(cmd, 0, sizeof(struct ethtool_cmd));
48         cmd->cmd = ETHTOOL_GSET;
49         return dev->ethtool_ops->get_settings(dev, cmd);
50 }
51 EXPORT_SYMBOL(__ethtool_get_settings);
52
53 /**
54  * llist_add_batch - add several linked entries in batch
55  * @new_first:  first entry in batch to be added
56  * @new_last:   last entry in batch to be added
57  * @head:       the head for your lock-less list
58  *
59  * Return whether list is empty before adding.
60  */
61 bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last,
62                      struct llist_head *head)
63 {
64         struct llist_node *entry, *old_entry;
65
66         entry = head->first;
67         for (;;) {
68                 old_entry = entry;
69                 new_last->next = entry;
70                 entry = cmpxchg(&head->first, old_entry, new_first);
71                 if (entry == old_entry)
72                         break;
73         }
74
75         return old_entry == NULL;
76 }
77 EXPORT_SYMBOL_GPL(llist_add_batch);
78
79 /**
80  * llist_del_first - delete the first entry of lock-less list
81  * @head:       the head for your lock-less list
82  *
83  * If list is empty, return NULL, otherwise, return the first entry
84  * deleted, this is the newest added one.
85  *
86  * Only one llist_del_first user can be used simultaneously with
87  * multiple llist_add users without lock.  Because otherwise
88  * llist_del_first, llist_add, llist_add (or llist_del_all, llist_add,
89  * llist_add) sequence in another user may change @head->first->next,
90  * but keep @head->first.  If multiple consumers are needed, please
91  * use llist_del_all or use lock between consumers.
92  */
93 struct llist_node *llist_del_first(struct llist_head *head)
94 {
95         struct llist_node *entry, *old_entry, *next;
96
97         entry = head->first;
98         for (;;) {
99                 if (entry == NULL)
100                         return NULL;
101                 old_entry = entry;
102                 next = entry->next;
103                 entry = cmpxchg(&head->first, old_entry, next);
104                 if (entry == old_entry)
105                         break;
106         }
107
108         return entry;
109 }
110 EXPORT_SYMBOL_GPL(llist_del_first);