highmem.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef _LINUX_HIGHMEM_H
  2. #define _LINUX_HIGHMEM_H
  3. #include <linux/config.h>
  4. #include <asm/pgalloc.h>
  5. #ifdef CONFIG_HIGHMEM
  6. extern struct page *highmem_start_page;
  7. #include <asm/highmem.h>
  8. /* declarations for linux/mm/highmem.c */
  9. unsigned int nr_free_highpages(void);
  10. extern struct buffer_head *create_bounce(int rw, struct buffer_head * bh_orig);
  11. static inline char *bh_kmap(struct buffer_head *bh)
  12. {
  13. return kmap(bh->b_page) + bh_offset(bh);
  14. }
  15. static inline void bh_kunmap(struct buffer_head *bh)
  16. {
  17. kunmap(bh->b_page);
  18. }
  19. /*
  20.  * remember to add offset! and never ever reenable interrupts between a
  21.  * bh_kmap_irq and bh_kunmap_irq!!
  22.  */
  23. static inline char *bh_kmap_irq(struct buffer_head *bh, unsigned long *flags)
  24. {
  25. unsigned long addr;
  26. __save_flags(*flags);
  27. /*
  28.  * could be low
  29.  */
  30. if (!PageHighMem(bh->b_page))
  31. return bh->b_data;
  32. /*
  33.  * it's a highmem page
  34.  */
  35. __cli();
  36. addr = (unsigned long) kmap_atomic(bh->b_page, KM_BH_IRQ);
  37. if (addr & ~PAGE_MASK)
  38. BUG();
  39. return (char *) addr + bh_offset(bh);
  40. }
  41. static inline void bh_kunmap_irq(char *buffer, unsigned long *flags)
  42. {
  43. unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
  44. kunmap_atomic((void *) ptr, KM_BH_IRQ);
  45. __restore_flags(*flags);
  46. }
  47. #else /* CONFIG_HIGHMEM */
  48. static inline unsigned int nr_free_highpages(void) { return 0; }
  49. static inline void *kmap(struct page *page) { return page_address(page); }
  50. #define kunmap(page) do { } while (0)
  51. #define kmap_atomic(page,idx) kmap(page)
  52. #define kunmap_atomic(page,idx) kunmap(page)
  53. #define bh_kmap(bh) ((bh)->b_data)
  54. #define bh_kunmap(bh) do { } while (0)
  55. #define bh_kmap_irq(bh, flags) ((bh)->b_data)
  56. #define bh_kunmap_irq(bh, flags) do { *(flags) = 0; } while (0)
  57. #endif /* CONFIG_HIGHMEM */
  58. /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
  59. static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
  60. {
  61. void *addr = kmap_atomic(page, KM_USER0);
  62. clear_user_page(addr, vaddr);
  63. kunmap_atomic(addr, KM_USER0);
  64. }
  65. static inline void clear_highpage(struct page *page)
  66. {
  67. clear_page(kmap(page));
  68. kunmap(page);
  69. }
  70. /*
  71.  * Same but also flushes aliased cache contents to RAM.
  72.  */
  73. static inline void memclear_highpage_flush(struct page *page, unsigned int offset, unsigned int size)
  74. {
  75. char *kaddr;
  76. if (offset + size > PAGE_SIZE)
  77. out_of_line_bug();
  78. kaddr = kmap(page);
  79. memset(kaddr + offset, 0, size);
  80. flush_dcache_page(page);
  81. flush_page_to_ram(page);
  82. kunmap(page);
  83. }
  84. static inline void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr)
  85. {
  86. char *vfrom, *vto;
  87. vfrom = kmap_atomic(from, KM_USER0);
  88. vto = kmap_atomic(to, KM_USER1);
  89. copy_user_page(vto, vfrom, vaddr);
  90. kunmap_atomic(vfrom, KM_USER0);
  91. kunmap_atomic(vto, KM_USER1);
  92. }
  93. #endif /* _LINUX_HIGHMEM_H */