rdma.m4: check if debugfs_create_bool() uses a bool or u32 pointer
[~tnikolova/compat/.git] / compat / compat-3.7.c
1 /*
2  * Copyright 2012  Luis R. Rodriguez <mcgrof@do-not-panic.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * Compatibility file for Linux wireless for kernels 3.7.
9  */
10
11 #include <linux/workqueue.h>
12 #include <linux/export.h>
13 #include <linux/file.h>
14
15 #define mod_delayed_work LINUX_BACKPORT(mod_delayed_work)
16 bool mod_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork,
17                       unsigned long delay)
18 {
19         cancel_delayed_work(dwork);
20         queue_delayed_work(wq, dwork, delay);
21         return false;
22 }
23 EXPORT_SYMBOL_GPL(mod_delayed_work);
24
25 /*
26  * Kernels >= 3.7 get their PCI-E Capabilities Register cached
27  * via the pci_dev->pcie_flags_reg so for older kernels we have
28  * no other option but to read this every single time we need
29  * it accessed. If we really cared to improve the efficiency
30  * of this we could try to find an unused u16 varible on the
31  * pci_dev but if we found it we likely would remove it from
32  * the kernel anyway right? Bite me.
33  */
34 #define pcie_flags_reg LINUX_BACKPORT(pcie_flags_reg)
35 static inline u16 pcie_flags_reg(struct pci_dev *dev)
36 {
37         int pos;
38         u16 reg16;
39
40         pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
41         if (!pos)
42                 return 0;
43
44         pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
45
46         return reg16;
47 }
48
49 #define pci_pcie_type LINUX_BACKPORT(pci_pcie_type)
50 static inline int pci_pcie_type(struct pci_dev *dev)
51 {
52         return (pcie_flags_reg(dev) & PCI_EXP_FLAGS_TYPE) >> 4;
53 }
54
55 #define pcie_cap_version LINUX_BACKPORT(pcie_cap_version)
56 static inline int pcie_cap_version(struct pci_dev *dev)
57 {
58         return pcie_flags_reg(dev) & PCI_EXP_FLAGS_VERS;
59 }
60
61 #define pcie_cap_has_devctl LINUX_BACKPORT(pcie_cap_has_devctl)
62 static inline bool pcie_cap_has_devctl(const struct pci_dev *dev)
63 {
64         return true;
65 }
66
67 #define pcie_cap_has_lnkctl LINUX_BACKPORT(pcie_cap_has_lnkctl)
68 static inline bool pcie_cap_has_lnkctl(struct pci_dev *dev)
69 {
70         int type = pci_pcie_type(dev);
71
72         return pcie_cap_version(dev) > 1 ||
73                type == PCI_EXP_TYPE_ROOT_PORT ||
74                type == PCI_EXP_TYPE_ENDPOINT ||
75                type == PCI_EXP_TYPE_LEG_END;
76 }
77
78 #define pcie_cap_has_sltctl LINUX_BACKPORT(pcie_cap_has_sltctl)
79 static inline bool pcie_cap_has_sltctl(struct pci_dev *dev)
80 {
81         int type = pci_pcie_type(dev);
82
83         return pcie_cap_version(dev) > 1 ||
84                type == PCI_EXP_TYPE_ROOT_PORT ||
85                (type == PCI_EXP_TYPE_DOWNSTREAM &&
86                 pcie_flags_reg(dev) & PCI_EXP_FLAGS_SLOT);
87 }
88
89 #define pcie_cap_has_rtctl LINUX_BACKPORT(pcie_cap_has_rtctl)
90 static inline bool pcie_cap_has_rtctl(struct pci_dev *dev)
91 {
92         int type = pci_pcie_type(dev);
93
94         return pcie_cap_version(dev) > 1 ||
95                type == PCI_EXP_TYPE_ROOT_PORT ||
96                type == PCI_EXP_TYPE_RC_EC;
97 }
98
99 #define pcie_capability_reg_implemented LINUX_BACKPORT(pcie_capability_reg_implemented)
100 static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos)
101 {
102         if (!pci_is_pcie(dev))
103                 return false;
104
105         switch (pos) {
106         case PCI_EXP_FLAGS_TYPE:
107                 return true;
108         case PCI_EXP_DEVCAP:
109         case PCI_EXP_DEVCTL:
110         case PCI_EXP_DEVSTA:
111                 return pcie_cap_has_devctl(dev);
112         case PCI_EXP_LNKCAP:
113         case PCI_EXP_LNKCTL:
114         case PCI_EXP_LNKSTA:
115                 return pcie_cap_has_lnkctl(dev);
116         case PCI_EXP_SLTCAP:
117         case PCI_EXP_SLTCTL:
118         case PCI_EXP_SLTSTA:
119                 return pcie_cap_has_sltctl(dev);
120         case PCI_EXP_RTCTL:
121         case PCI_EXP_RTCAP:
122         case PCI_EXP_RTSTA:
123                 return pcie_cap_has_rtctl(dev);
124         case PCI_EXP_DEVCAP2:
125         case PCI_EXP_DEVCTL2:
126         case PCI_EXP_LNKCAP2:
127         case PCI_EXP_LNKCTL2:
128         case PCI_EXP_LNKSTA2:
129                 return pcie_cap_version(dev) > 1;
130         default:
131                 return false;
132         }
133 }
134
135 /*
136  * Note that these accessor functions are only for the "PCI Express
137  * Capability" (see PCIe spec r3.0, sec 7.8).  They do not apply to the
138  * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.)
139  */
140 #define pcie_capability_read_word LINUX_BACKPORT(pcie_capability_read_word)
141 int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
142 {
143         int ret;
144
145         *val = 0;
146         if (pos & 1)
147                 return -EINVAL;
148
149         if (pcie_capability_reg_implemented(dev, pos)) {
150                 ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val);
151                 /*
152                  * Reset *val to 0 if pci_read_config_word() fails, it may
153                  * have been written as 0xFFFF if hardware error happens
154                  * during pci_read_config_word().
155                  */
156                 if (ret)
157                         *val = 0;
158                 return ret;
159         }
160
161         /*
162          * For Functions that do not implement the Slot Capabilities,
163          * Slot Status, and Slot Control registers, these spaces must
164          * be hardwired to 0b, with the exception of the Presence Detect
165          * State bit in the Slot Status register of Downstream Ports,
166          * which must be hardwired to 1b.  (PCIe Base Spec 3.0, sec 7.8)
167          */
168         if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA &&
169                  pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) {
170                 *val = PCI_EXP_SLTSTA_PDS;
171         }
172
173         return 0;
174 }
175 EXPORT_SYMBOL(pcie_capability_read_word);
176
177 #define pcie_capability_read_dword LINUX_BACKPORT(pcie_capability_read_dword)
178 int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
179 {
180         int ret;
181
182         *val = 0;
183         if (pos & 3)
184                 return -EINVAL;
185
186         if (pcie_capability_reg_implemented(dev, pos)) {
187                 ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val);
188                 /*
189                  * Reset *val to 0 if pci_read_config_dword() fails, it may
190                  * have been written as 0xFFFFFFFF if hardware error happens
191                  * during pci_read_config_dword().
192                  */
193                 if (ret)
194                         *val = 0;
195                 return ret;
196         }
197
198         if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL &&
199                  pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) {
200                 *val = PCI_EXP_SLTSTA_PDS;
201         }
202
203         return 0;
204 }
205 EXPORT_SYMBOL(pcie_capability_read_dword);
206
207 #define pcie_capability_write_word LINUX_BACKPORT(pcie_capability_write_word)
208 int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val)
209 {
210         if (pos & 1)
211                 return -EINVAL;
212
213         if (!pcie_capability_reg_implemented(dev, pos))
214                 return 0;
215
216         return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val);
217 }
218 EXPORT_SYMBOL(pcie_capability_write_word);
219
220 #define pcie_capability_write_dword LINUX_BACKPORT(pcie_capability_write_dword)
221 int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val)
222 {
223         if (pos & 3)
224                 return -EINVAL;
225
226         if (!pcie_capability_reg_implemented(dev, pos))
227                 return 0;
228
229         return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val);
230 }
231 EXPORT_SYMBOL(pcie_capability_write_dword);
232
233 #define pcie_capability_clear_and_set_word LINUX_BACKPORT(pcie_capability_clear_and_set_word)
234 int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
235                                        u16 clear, u16 set)
236 {
237         int ret;
238         u16 val;
239
240         ret = pcie_capability_read_word(dev, pos, &val);
241         if (!ret) {
242                 val &= ~clear;
243                 val |= set;
244                 ret = pcie_capability_write_word(dev, pos, val);
245         }
246
247         return ret;
248 }
249 EXPORT_SYMBOL(pcie_capability_clear_and_set_word);
250
251 #define pcie_capability_clear_and_set_dword LINUX_BACKPORT(pcie_capability_clear_and_set_dword)
252 int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
253                                         u32 clear, u32 set)
254 {
255         int ret;
256         u32 val;
257
258         ret = pcie_capability_read_dword(dev, pos, &val);
259         if (!ret) {
260                 val &= ~clear;
261                 val |= set;
262                 ret = pcie_capability_write_dword(dev, pos, val);
263         }
264
265         return ret;
266 }
267 EXPORT_SYMBOL(pcie_capability_clear_and_set_dword);
268
269 /* Actually fget_light is defined in fs/file.c but only 3.7 exports it.
270  * Lets export it here.
271  */
272 struct file *fget_light(unsigned int fd, int *fput_needed)
273 {
274         struct file *file;
275         struct files_struct *files = current->files;
276
277         *fput_needed = 0;
278         if (atomic_read(&files->count) == 1) {
279                 file = fcheck_files(files, fd);
280                 if (file && (file->f_mode & FMODE_PATH))
281                         file = NULL;
282         } else {
283                 rcu_read_lock();
284                 file = fcheck_files(files, fd);
285                 if (file) {
286                         if (!(file->f_mode & FMODE_PATH) &&
287                             atomic_long_inc_not_zero(&file->f_count))
288                                 *fput_needed = 1;
289                         else
290                                 /* Didn't get the reference, someone's freed */
291                                 file = NULL;
292                 }
293                 rcu_read_unlock();
294         }
295
296         return file;
297 }
298 EXPORT_SYMBOL(fget_light);