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