compat.h 7.5 KB

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