- supported.conf: Added sparse_keymap (eeepc_laptop depends on it)
[linux-flexiantxendom0-3.2.10.git] / drivers / net / sfc / sfc_resource / ci / efhw / iopage_types.h
1 /****************************************************************************
2  * Driver for Solarflare network controllers -
3  *          resource management for Xen backend, OpenOnload, etc
4  *           (including support for SFE4001 10GBT NIC)
5  *
6  * This file provides struct efhw_page and struct efhw_iopage for Linux
7  * kernel.
8  *
9  * Copyright 2005-2007: Solarflare Communications Inc,
10  *                      9501 Jeronimo Road, Suite 250,
11  *                      Irvine, CA 92618, USA
12  *
13  * Developed and maintained by Solarflare Communications:
14  *                      <linux-xen-drivers@solarflare.com>
15  *                      <onload-dev@solarflare.com>
16  *
17  * Certain parts of the driver were implemented by
18  *          Alexandra Kossovsky <Alexandra.Kossovsky@oktetlabs.ru>
19  *          OKTET Labs Ltd, Russia,
20  *          http://oktetlabs.ru, <info@oktetlabs.ru>
21  *          by request of Solarflare Communications
22  *
23  *
24  * This program is free software; you can redistribute it and/or modify it
25  * under the terms of the GNU General Public License version 2 as published
26  * by the Free Software Foundation, incorporated herein by reference.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31  * GNU General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program; if not, write to the Free Software
35  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
36  ****************************************************************************
37  */
38
39 #ifndef __CI_EFHW_IOPAGE_LINUX_H__
40 #define __CI_EFHW_IOPAGE_LINUX_H__
41
42 #include <linux/gfp.h>
43 #include <linux/hardirq.h>
44 #include <linux/errno.h>
45 #include <ci/efhw/debug.h>
46
47 /*--------------------------------------------------------------------
48  *
49  * struct efhw_page: A single page of memory.  Directly mapped in the
50  * driver, and can be mapped to userlevel.
51  *
52  *--------------------------------------------------------------------*/
53
54 struct efhw_page {
55         unsigned long kva;
56 };
57
58 static inline int efhw_page_alloc(struct efhw_page *p)
59 {
60         p->kva = __get_free_page(in_interrupt()? GFP_ATOMIC : GFP_KERNEL);
61         return p->kva ? 0 : -ENOMEM;
62 }
63
64 static inline int efhw_page_alloc_zeroed(struct efhw_page *p)
65 {
66         p->kva = get_zeroed_page(in_interrupt()? GFP_ATOMIC : GFP_KERNEL);
67         return p->kva ? 0 : -ENOMEM;
68 }
69
70 static inline void efhw_page_free(struct efhw_page *p)
71 {
72         free_page(p->kva);
73         EFHW_DO_DEBUG(memset(p, 0, sizeof(*p)));
74 }
75
76 static inline char *efhw_page_ptr(struct efhw_page *p)
77 {
78         return (char *)p->kva;
79 }
80
81 static inline unsigned efhw_page_pfn(struct efhw_page *p)
82 {
83         return (unsigned)(__pa(p->kva) >> PAGE_SHIFT);
84 }
85
86 static inline void efhw_page_mark_invalid(struct efhw_page *p)
87 {
88         p->kva = 0;
89 }
90
91 static inline int efhw_page_is_valid(struct efhw_page *p)
92 {
93         return p->kva != 0;
94 }
95
96 static inline void efhw_page_init_from_va(struct efhw_page *p, void *va)
97 {
98         p->kva = (unsigned long)va;
99 }
100
101 /*--------------------------------------------------------------------
102  *
103  * struct efhw_iopage: A single page of memory.  Directly mapped in the driver,
104  * and can be mapped to userlevel.  Can also be accessed by the NIC.
105  *
106  *--------------------------------------------------------------------*/
107
108 struct efhw_iopage {
109         struct efhw_page p;
110         dma_addr_t dma_addr;
111 };
112
113 static inline dma_addr_t efhw_iopage_dma_addr(struct efhw_iopage *p)
114 {
115         return p->dma_addr;
116 }
117
118 #define efhw_iopage_ptr(iop)            efhw_page_ptr(&(iop)->p)
119 #define efhw_iopage_pfn(iop)            efhw_page_pfn(&(iop)->p)
120 #define efhw_iopage_mark_invalid(iop)   efhw_page_mark_invalid(&(iop)->p)
121 #define efhw_iopage_is_valid(iop)       efhw_page_is_valid(&(iop)->p)
122
123 /*--------------------------------------------------------------------
124  *
125  * struct efhw_iopages: A set of pages that are contiguous in physical
126  * memory.  Directly mapped in the driver, and can be mapped to userlevel.
127  * Can also be accessed by the NIC.
128  *
129  * NB. The O/S may be unwilling to allocate many, or even any of these.  So
130  * only use this type where the NIC really needs a physically contiguous
131  * buffer.
132  *
133  *--------------------------------------------------------------------*/
134
135 struct efhw_iopages {
136         caddr_t kva;
137         unsigned order;
138         dma_addr_t dma_addr;
139 };
140
141 static inline caddr_t efhw_iopages_ptr(struct efhw_iopages *p)
142 {
143         return p->kva;
144 }
145
146 static inline unsigned efhw_iopages_pfn(struct efhw_iopages *p)
147 {
148         return (unsigned)(__pa(p->kva) >> PAGE_SHIFT);
149 }
150
151 static inline dma_addr_t efhw_iopages_dma_addr(struct efhw_iopages *p)
152 {
153         return p->dma_addr;
154 }
155
156 static inline unsigned efhw_iopages_size(struct efhw_iopages *p)
157 {
158         return 1u << (p->order + PAGE_SHIFT);
159 }
160
161 /* struct efhw_iopage <-> struct efhw_iopages conversions for handling
162  * physically contiguous allocations in iobufsets for iSCSI.  This allows
163  * the essential information about contiguous allocations from
164  * efhw_iopages_alloc() to be saved away in the struct efhw_iopage array in
165  * an iobufset.  (Changing the iobufset resource to use a union type would
166  * involve a lot of code changes, and make the iobufset's metadata larger
167  * which could be bad as it's supposed to fit into a single page on some
168  * platforms.)
169  */
170 static inline void
171 efhw_iopage_init_from_iopages(struct efhw_iopage *iopage,
172                               struct efhw_iopages *iopages, unsigned pageno)
173 {
174         iopage->p.kva = ((unsigned long)efhw_iopages_ptr(iopages))
175             + (pageno * PAGE_SIZE);
176         iopage->dma_addr = efhw_iopages_dma_addr(iopages) +
177             (pageno * PAGE_SIZE);
178 }
179
180 static inline void
181 efhw_iopages_init_from_iopage(struct efhw_iopages *iopages,
182                               struct efhw_iopage *iopage, unsigned order)
183 {
184         iopages->kva = (caddr_t) efhw_iopage_ptr(iopage);
185         EFHW_ASSERT(iopages->kva);
186         iopages->order = order;
187         iopages->dma_addr = efhw_iopage_dma_addr(iopage);
188 }
189
190 #endif /* __CI_EFHW_IOPAGE_LINUX_H__ */