/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to driver/compat.h

  • Committer: Suren A. Chilingaryan
  • Date: 2011-02-13 02:07:11 UTC
  • Revision ID: csa@dside.dyndns.org-20110213020711-y9bjh3n4ke6p4t4n
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 *
 
3
 * @file compat.h
 
4
 * @author Michael Stapelberg
 
5
 * @date 2009-04-05
 
6
 * @brief Contains compatibility definitions for the different linux kernel versions to avoid
 
7
 * putting ifdefs all over the driver code.
 
8
 *
 
9
 */
 
10
#ifndef _COMPAT_H
 
11
#define _COMPAT_H
 
12
 
 
13
/* dev_name is the wrapper one needs to use to access what was formerly called
 
14
 * bus_id in struct device. However, before 2.6.27, direct access was necessary,
 
15
 * so we provide our own version. */
 
16
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
 
17
static inline const char *dev_name(struct device *dev) {
 
18
        return dev->bus_id;
 
19
}
 
20
#endif
 
21
 
 
22
/* SetPageLocked disappeared in v2.6.27 */
 
23
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
 
24
        #define compat_lock_page SetPageLocked
 
25
        #define compat_unlock_page ClearPageLocked
 
26
#else
 
27
        /* in v2.6.28, __set_page_locked and __clear_page_locked was introduced */
 
28
        #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
 
29
                #define compat_lock_page __set_page_locked
 
30
                #define compat_unlock_page __clear_page_locked
 
31
        #else
 
32
                /* However, in v2.6.27 itself, neither of them is there, so
 
33
                 * we need to use our own function fiddling with bits inside
 
34
                 * the page struct :-\ */
 
35
                static inline void compat_lock_page(struct page *page) {
 
36
                        __set_bit(PG_locked, &page->flags);
 
37
                }
 
38
 
 
39
                static inline void compat_unlock_page(struct page *page) {
 
40
                        __clear_bit(PG_locked, &page->flags);
 
41
                }
 
42
        #endif
 
43
#endif
 
44
 
 
45
/* Before 2.6.13, simple_class was the standard interface. Nowadays, it's just called class */
 
46
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
 
47
 
 
48
        #define class_compat class_simple
 
49
 
 
50
        /* These functions are redirected to their old corresponding functions */
 
51
        #define class_create(module, name) class_simple_create(module, name)
 
52
        #define class_destroy(type) class_simple_destroy(type)
 
53
        #define class_device_destroy(unused, devno) class_simple_device_remove(devno)
 
54
        #define class_device_create(type, unused, devno, devpointer, nameformat, minor, unused) \
 
55
                class_simple_device_add(type, devno, devpointer, nameformat, minor)
 
56
        #define class_set_devdata(classdev, privdata) classdev->class_data = privdata
 
57
        #define DEVICE_ATTR_COMPAT
 
58
        #define sysfs_attr_def_name(name) class_device_attr_##name
 
59
        #define sysfs_attr_def_pointer privdata->class_dev
 
60
        #define SYSFS_GET_FUNCTION(name) ssize_t name(struct class_device *cls, char *buf)
 
61
        #define SYSFS_SET_FUNCTION(name) ssize_t name(struct class_device *cls, const char *buf, size_t count)
 
62
        #define SYSFS_GET_PRIVDATA (pcidriver_privdata_t*)cls->class_data
 
63
 
 
64
#else
 
65
 
 
66
/* In 2.6.26, device.h was changed quite significantly. Luckily, it only affected
 
67
   type/function names, for the most part. */
 
68
//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
 
69
        #define class_device_attribute device_attribute
 
70
        #define CLASS_DEVICE_ATTR DEVICE_ATTR
 
71
        #define class_device device
 
72
        #define class_data dev
 
73
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
 
74
        #define class_device_create(type, parent, devno, devpointer, nameformat, minor, privdata) \
 
75
                device_create(type, parent, devno, privdata, nameformat, minor)
 
76
#else
 
77
        #define class_device_create(type, parent, devno, devpointer, nameformat, minor, unused) \
 
78
                device_create(type, parent, devno, nameformat, minor)
 
79
#endif
 
80
        #define class_device_create_file device_create_file
 
81
        #define class_device_remove_file device_remove_file
 
82
        #define class_device_destroy device_destroy
 
83
        #define DEVICE_ATTR_COMPAT struct device_attribute *attr,
 
84
        #define class_set_devdata dev_set_drvdata
 
85
 
 
86
        #define sysfs_attr_def_name(name) dev_attr_##name
 
87
        #define sysfs_attr_def_pointer privdata->class_dev
 
88
        #define SYSFS_GET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, char *buf)
 
89
        #define SYSFS_SET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 
90
        #define SYSFS_GET_PRIVDATA dev_get_drvdata(dev)
 
91
 
 
92
//#endif
 
93
 
 
94
#define class_compat class
 
95
 
 
96
#endif
 
97
 
 
98
/* The arguments of IRQ handlers have been changed in 2.6.19. It's very likely that
 
99
   int irq will disappear somewhen in the future (current is 2.6.29), too. */
 
100
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
 
101
        #define IRQ_HANDLER_FUNC(name) irqreturn_t name(int irq, void *dev_id)
 
102
#else
 
103
        #define IRQ_HANDLER_FUNC(name) irqreturn_t name(int irq, void *dev_id, struct pt_regs *regs)
 
104
#endif
 
105
 
 
106
/* atomic_inc_return appeared in 2.6.9, at least in CERN scientific linux, provide
 
107
   compatibility wrapper for older kernels */
 
108
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
 
109
static int atomic_inc_return(atomic_t *variable) {
 
110
        atomic_inc(variable);
 
111
        return atomic_read(variable);
 
112
}
 
113
#endif
 
114
 
 
115
/* sg_set_page is available starting at 2.6.24 */
 
116
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
 
117
 
 
118
#define sg_set_page(sg, set_page, set_length, set_offset) do { \
 
119
        (sg)->page = set_page; \
 
120
        (sg)->length = set_length; \
 
121
        (sg)->offset = set_offset; \
 
122
} while (0)
 
123
 
 
124
#endif
 
125
 
 
126
/* Before 2.6.20, disable was not an atomic counter, so this check was needed */
 
127
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
 
128
#define pci_disable_device(pdev) do { \
 
129
        if (pdev->is_enabled) \
 
130
                pci_disable_device(pdev); \
 
131
} while (0)
 
132
#endif
 
133
 
 
134
/* Before 2.6.24, scatter/gather lists did not need to be initialized */
 
135
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
 
136
        #define sg_init_table(sg, nr_pages)
 
137
#endif
 
138
 
 
139
/* SA_SHIRQ was renamed to IRQF_SHARED in 2.6.24 */
 
140
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
 
141
        #define request_irq(irq, irq_handler, modname, privdata) request_irq(irq, irq_handler, IRQF_SHARED, modname, privdata)
 
142
#else
 
143
        #define request_irq(irq, irq_handler, modname, privdata) request_irq(irq, irq_handler, SA_SHIRQ, modname, privdata)
 
144
#endif
 
145
 
 
146
/* In 2.6.13, io_remap_page_range was removed in favor for io_remap_pfn_range which works on
 
147
   more platforms and allows more memory space */
 
148
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
 
149
#define io_remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \
 
150
        io_remap_pfn_range(vmap, vm_start, (bar_addr >> PAGE_SHIFT), bar_length, vm_page_prot)
 
151
#else
 
152
#define io_remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \
 
153
        io_remap_page_range(vmap, vm_start, bar_addr, bar_length, vm_page_prot)
 
154
#endif
 
155
 
 
156
/* In 2.6.10, remap_pfn_range was introduced, see io_remap_pfn_range_compat */
 
157
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
 
158
#define remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \
 
159
        remap_pfn_range(vmap, vm_start, (bar_addr >> PAGE_SHIFT), bar_length, vm_page_prot)
 
160
 
 
161
#define remap_pfn_range_cpua_compat(vmap, vm_start, cpua, size, vm_page_prot) \
 
162
        remap_pfn_range(vmap, vm_start, page_to_pfn(virt_to_page((void*)cpua)), size, vm_page_prot)
 
163
 
 
164
#else
 
165
#define remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \
 
166
        remap_page_range(vmap, vm_start, bar_addr, bar_length, vm_page_prot)
 
167
 
 
168
#define remap_pfn_range_cpua_compat(vmap, vm_start, cpua, size, vm_page_prot) \
 
169
        remap_page_range(vmap, vm_start, virt_to_phys((void*)cpua), size, vm_page_prot)
 
170
#endif
 
171
 
 
172
/**
 
173
 * Go over the pages of the kmem buffer, and mark them as reserved.
 
174
 * This is needed, otherwise mmaping the kernel memory to user space
 
175
 * will fail silently (mmaping /dev/null) when using remap_xx_range.
 
176
 */
 
177
static inline void set_pages_reserved_compat(unsigned long cpua, unsigned long size)
 
178
{
 
179
        /* Starting in 2.6.15, the PG_RESERVED bit was removed.
 
180
           See also http://lwn.net/Articles/161204/ */
 
181
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
 
182
        struct page *page, *last_page;
 
183
 
 
184
        page = virt_to_page(cpua);
 
185
        last_page = virt_to_page(cpua + size - 1);
 
186
 
 
187
        for (; page <= last_page; page++)
 
188
               SetPageReserved(page);
 
189
#endif
 
190
}
 
191
 
 
192
#endif