Backport pm-qos for kernels <= 2.6.24
[~emulex/for-vlad/old/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
13 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
14
15 #include <linux/pci.h>
16 #include <linux/mmc/sdio.h>
17 #include <linux/mmc/sdio_func.h>
18 #include <linux/mmc/card.h>
19 #include <linux/mmc/host.h>
20
21 /* rfkill notification chain */
22 #define RFKILL_STATE_CHANGED            0x0001  /* state of a normal rfkill
23                                                         switch has changed */
24
25 /*
26  * e5899e1b7d73e67de758a32174a859cc2586c0b9 made pci_pme_capable() external,
27  * it was defined internally, some drivers want access to this information.
28  *
29  * Unfortunately the old kernels do not have ->pm_cap or ->pme_support so
30  * we have to call the PCI routines directly.
31  */
32
33 /**
34  * pci_pme_capable - check the capability of PCI device to generate PME#
35  * @dev: PCI device to handle.
36  * @state: PCI state from which device will issue PME#.
37  *
38  * This is the backport code for older kernels for compat-wireless, we read stuff
39  * from the initialization stuff from pci_pm_init().
40  */
41 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
42 {
43         int pm;
44         u16 pmc = 0;
45         u16 pme_support; /* as from the pci dev */
46         /* find PCI PM capability in list */
47         pm = pci_find_capability(dev, PCI_CAP_ID_PM);
48         if (!pm)
49                 return false;
50
51         if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
52                 dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n",
53                         pmc & PCI_PM_CAP_VER_MASK);
54                 return false;
55         }
56
57         pmc &= PCI_PM_CAP_PME_MASK;
58
59         if (!pmc)
60                 return false;
61
62         pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
63
64         /* Check device's ability to generate PME# */
65
66         return !!(pme_support & (1 << state));
67 }
68 EXPORT_SYMBOL(pci_pme_capable);
69
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(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
205
206 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */
207