devcoredump.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * This file is provided under the GPLv2 license.
  3. *
  4. * GPL LICENSE SUMMARY
  5. *
  6. * Copyright(c) 2015 Intel Deutschland GmbH
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of version 2 of the GNU General Public License as
  10. * published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * The full GNU General Public License is included in this distribution
  18. * in the file called COPYING.
  19. */
  20. #ifndef __DEVCOREDUMP_H
  21. #define __DEVCOREDUMP_H
  22. #include <linux/device.h>
  23. #include <linux/module.h>
  24. #include <linux/vmalloc.h>
  25. #include <linux/scatterlist.h>
  26. #include <linux/slab.h>
  27. /*
  28. * _devcd_free_sgtable - free all the memory of the given scatterlist table
  29. * (i.e. both pages and scatterlist instances)
  30. * NOTE: if two tables allocated and chained using the sg_chain function then
  31. * this function should be called only once on the first table
  32. * @table: pointer to sg_table to free
  33. */
  34. static inline void _devcd_free_sgtable(struct scatterlist *table)
  35. {
  36. int i;
  37. struct page *page;
  38. struct scatterlist *iter;
  39. struct scatterlist *delete_iter;
  40. /* free pages */
  41. iter = table;
  42. for_each_sg(table, iter, sg_nents(table), i) {
  43. page = sg_page(iter);
  44. if (page)
  45. __free_page(page);
  46. }
  47. /* then free all chained tables */
  48. iter = table;
  49. delete_iter = table; /* always points on a head of a table */
  50. while (!sg_is_last(iter)) {
  51. iter++;
  52. if (sg_is_chain(iter)) {
  53. iter = sg_chain_ptr(iter);
  54. kfree(delete_iter);
  55. delete_iter = iter;
  56. }
  57. }
  58. /* free the last table */
  59. kfree(delete_iter);
  60. }
  61. #ifdef CONFIG_DEV_COREDUMP
  62. void dev_coredumpv(struct device *dev, void *data, size_t datalen,
  63. gfp_t gfp);
  64. void dev_coredumpm(struct device *dev, struct module *owner,
  65. void *data, size_t datalen, gfp_t gfp,
  66. ssize_t (*read)(char *buffer, loff_t offset, size_t count,
  67. void *data, size_t datalen),
  68. void (*free)(void *data));
  69. void dev_coredumpsg(struct device *dev, struct scatterlist *table,
  70. size_t datalen, gfp_t gfp);
  71. #else
  72. static inline void dev_coredumpv(struct device *dev, void *data,
  73. size_t datalen, gfp_t gfp)
  74. {
  75. vfree(data);
  76. }
  77. static inline void
  78. dev_coredumpm(struct device *dev, struct module *owner,
  79. void *data, size_t datalen, gfp_t gfp,
  80. ssize_t (*read)(char *buffer, loff_t offset, size_t count,
  81. void *data, size_t datalen),
  82. void (*free)(void *data))
  83. {
  84. free(data);
  85. }
  86. static inline void dev_coredumpsg(struct device *dev, struct scatterlist *table,
  87. size_t datalen, gfp_t gfp)
  88. {
  89. _devcd_free_sgtable(table);
  90. }
  91. #endif /* CONFIG_DEV_COREDUMP */
  92. #endif /* __DEVCOREDUMP_H */