2 * Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
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.
8 * Compatibility file for Linux wireless for kernels 2.6.27
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>
20 /* rfkill notification chain */
21 #define RFKILL_STATE_CHANGED 0x0001 /* state of a normal rfkill
25 * e5899e1b7d73e67de758a32174a859cc2586c0b9 made pci_pme_capable() external,
26 * it was defined internally, some drivers want access to this information.
28 * Unfortunately the old kernels do not have ->pm_cap or ->pme_support so
29 * we have to call the PCI routines directly.
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#.
37 * This is the backport code for older kernels for compat-wireless, we read stuff
38 * from the initialization stuff from pci_pm_init().
40 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
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);
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);
56 pmc &= PCI_PM_CAP_PME_MASK;
61 pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
63 /* Check device's ability to generate PME# */
65 return !!(pme_support & (1 << state));
67 EXPORT_SYMBOL_GPL(pci_pme_capable);
69 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
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
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).
79 * Returns the improved size, which might be unmodified.
81 * Note that this function is only relevant when issuing a
82 * single scatter gather entry.
84 unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
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
91 sz = ((sz + 3) / 4) * 4;
95 EXPORT_SYMBOL_GPL(mmc_align_data_size);
98 * Calculate the maximum byte mode transfer size
100 static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
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 */
109 * sdio_align_size - pads a transfer size to a more optimal value
110 * @func: SDIO function
111 * @sz: original transfer size
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).
117 * If possible, it will also adjust the size so that it can be
118 * handled in just a single request.
120 * Returns the improved size, which might be unmodified.
122 unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
124 unsigned int orig_sz;
125 unsigned int blk_sz, byte_sz;
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.
135 sz = mmc_align_data_size(func->card, sz);
138 * If we can still do this with just a byte transfer, then
141 if (sz <= sdio_max_byte_size(func))
144 if (func->card->cccr.multi_block) {
146 * Check if the transfer is already block aligned
148 if ((sz % func->cur_blksize) == 0)
152 * Realign it so that it can be done with one request,
153 * and recheck if the controller still likes it.
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);
160 * This value is only good if it is still just
163 if ((blk_sz % func->cur_blksize) == 0)
167 * We failed to do one request, but at least try to
168 * pad the remainder properly.
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;
178 * We need multiple requests, so first check that the
179 * controller can handle the chunk size;
181 chunk_sz = mmc_align_data_size(func->card,
182 sdio_max_byte_size(func));
183 if (chunk_sz == sdio_max_byte_size(func)) {
185 * Fix up the size of the remainder (if any)
187 byte_sz = orig_sz % chunk_sz;
189 byte_sz = mmc_align_data_size(func->card,
193 return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
198 * The controller is simply incapable of transferring the size
199 * we want in decent manner, so just return the original size.
203 EXPORT_SYMBOL_GPL(sdio_align_size);
204 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) */
206 #ifdef CONFIG_DEBUG_FS
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);
212 void debugfs_remove_recursive(struct dentry *dentry)
214 struct dentry *last = NULL;
217 if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode)
220 while (dentry != last) {
221 struct dentry *child = dentry;
223 /* Find a child without children */
224 while (!list_empty(&child->d_subdirs))
225 child = list_entry(child->d_subdirs.next,
229 /* Bail out if we already tried to remove that entry */
234 debugfs_remove(child);
237 EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
238 #endif /* CONFIG_DEBUG_FS */