rdma.m4: check if debugfs_create_bool() uses a bool or u32 pointer
[~tnikolova/compat/.git] / compat / compat-2.6.27.c
1 /*
2  * Copyright 2007       Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
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 2.6.27
9  */
10
11 #include <linux/compat.h>
12 #include <linux/pci.h>
13 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
14 #include <linux/mmc/sdio.h>
15 #include <linux/mmc/sdio_func.h>
16 #include <linux/mmc/card.h>
17 #include <linux/mmc/host.h>
18 #endif
19
20 /* rfkill notification chain */
21 #define RFKILL_STATE_CHANGED            0x0001  /* state of a normal rfkill
22                                                         switch has changed */
23
24 /*
25  * e5899e1b7d73e67de758a32174a859cc2586c0b9 made pci_pme_capable() external,
26  * it was defined internally, some drivers want access to this information.
27  *
28  * Unfortunately the old kernels do not have ->pm_cap or ->pme_support so
29  * we have to call the PCI routines directly.
30  */
31
32 /**
33  * pci_pme_capable - check the capability of PCI device to generate PME#
34  * @dev: PCI device to handle.
35  * @state: PCI state from which device will issue PME#.
36  *
37  * This is the backport code for older kernels for compat-wireless, we read stuff
38  * from the initialization stuff from pci_pm_init().
39  */
40 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
41 {
42         int pm;
43         u16 pmc = 0;
44         u16 pme_support; /* as from the pci dev */
45         /* find PCI PM capability in list */
46         pm = pci_find_capability(dev, PCI_CAP_ID_PM);
47         if (!pm)
48                 return false;
49
50         if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
51                 dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n",
52                         pmc & PCI_PM_CAP_VER_MASK);
53                 return false;
54         }
55
56         pmc &= PCI_PM_CAP_PME_MASK;
57
58         if (!pmc)
59                 return false;
60
61         pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
62
63         /* Check device's ability to generate PME# */
64
65         return !!(pme_support & (1 << state));
66 }
67 EXPORT_SYMBOL_GPL(pci_pme_capable);
68
69 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
70 /**
71  *      mmc_align_data_size - pads a transfer size to a more optimal value
72  *      @card: the MMC card associated with the data transfer
73  *      @sz: original transfer size
74  *
75  *      Pads the original data size with a number of extra bytes in
76  *      order to avoid controller bugs and/or performance hits
77  *      (e.g. some controllers revert to PIO for certain sizes).
78  *
79  *      Returns the improved size, which might be unmodified.
80  *
81  *      Note that this function is only relevant when issuing a
82  *      single scatter gather entry.
83  */
84 unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
85 {
86         /*
87         * FIXME: We don't have a system for the controller to tell
88         * the core about its problems yet, so for now we just 32-bit
89         * align the size.
90         */
91         sz = ((sz + 3) / 4) * 4;
92
93         return sz;
94 }
95 EXPORT_SYMBOL_GPL(mmc_align_data_size);
96
97 /*
98  * Calculate the maximum byte mode transfer size
99  */
100 static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
101 {
102         unsigned int mval = (unsigned int) min(func->card->host->max_seg_size,
103                             func->card->host->max_blk_size);
104         mval = min(mval, func->max_blksize);
105         return min(mval, 512u); /* maximum size for byte mode */
106 }
107
108 /**
109  *      sdio_align_size - pads a transfer size to a more optimal value
110  *      @func: SDIO function
111  *      @sz: original transfer size
112  *
113  *      Pads the original data size with a number of extra bytes in
114  *      order to avoid controller bugs and/or performance hits
115  *      (e.g. some controllers revert to PIO for certain sizes).
116  *
117  *      If possible, it will also adjust the size so that it can be
118  *      handled in just a single request.
119  *
120  *      Returns the improved size, which might be unmodified.
121  */
122 unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
123 {
124         unsigned int orig_sz;
125         unsigned int blk_sz, byte_sz;
126         unsigned chunk_sz;
127
128         orig_sz = sz;
129
130         /*
131          * Do a first check with the controller, in case it
132          * wants to increase the size up to a point where it
133          * might need more than one block.
134          */
135         sz = mmc_align_data_size(func->card, sz);
136
137         /*
138          * If we can still do this with just a byte transfer, then
139          * we're done.
140          */
141         if (sz <= sdio_max_byte_size(func))
142                 return sz;
143
144         if (func->card->cccr.multi_block) {
145                 /*
146                  * Check if the transfer is already block aligned
147                  */
148                 if ((sz % func->cur_blksize) == 0)
149                         return sz;
150
151                 /*
152                  * Realign it so that it can be done with one request,
153                  * and recheck if the controller still likes it.
154                  */
155                 blk_sz = ((sz + func->cur_blksize - 1) /
156                         func->cur_blksize) * func->cur_blksize;
157                 blk_sz = mmc_align_data_size(func->card, blk_sz);
158
159                 /*
160                  * This value is only good if it is still just
161                  * one request.
162                  */
163                 if ((blk_sz % func->cur_blksize) == 0)
164                         return blk_sz;
165
166                 /*
167                  * We failed to do one request, but at least try to
168                  * pad the remainder properly.
169                  */
170                 byte_sz = mmc_align_data_size(func->card,
171                                 sz % func->cur_blksize);
172                 if (byte_sz <= sdio_max_byte_size(func)) {
173                         blk_sz = sz / func->cur_blksize;
174                         return blk_sz * func->cur_blksize + byte_sz;
175                 }
176         } else {
177                 /*
178                  * We need multiple requests, so first check that the
179                  * controller can handle the chunk size;
180                  */
181                 chunk_sz = mmc_align_data_size(func->card,
182                                 sdio_max_byte_size(func));
183                 if (chunk_sz == sdio_max_byte_size(func)) {
184                         /*
185                          * Fix up the size of the remainder (if any)
186                          */
187                         byte_sz = orig_sz % chunk_sz;
188                         if (byte_sz) {
189                                 byte_sz = mmc_align_data_size(func->card,
190                                                 byte_sz);
191                         }
192
193                         return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
194                 }
195         }
196
197         /*
198          * The controller is simply incapable of transferring the size
199          * we want in decent manner, so just return the original size.
200          */
201         return orig_sz;
202 }
203 EXPORT_SYMBOL_GPL(sdio_align_size);
204 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) */
205
206 #ifdef CONFIG_DEBUG_FS
207 /*
208  * Backport of debugfs_remove_recursive() without using the internals globals
209  * which are used by the kernel's version with:
210  * simple_release_fs(&debugfs_mount, &debugfs_mount_count);
211  */
212 void debugfs_remove_recursive(struct dentry *dentry)
213 {
214         struct dentry *last = NULL;
215
216         /* Sanity checks */
217         if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode)
218                 return;
219
220         while (dentry != last) {
221                 struct dentry *child = dentry;
222
223                 /* Find a child without children */
224                 while (!list_empty(&child->d_subdirs))
225                         child = list_entry(child->d_subdirs.next,
226                                            struct dentry,
227                                            d_u.d_child);
228
229                 /* Bail out if we already tried to remove that entry */
230                 if (child == last)
231                         return;
232
233                 last = child;
234                 debugfs_remove(child);
235         }
236 }
237 EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
238 #endif /* CONFIG_DEBUG_FS */
239