0001
0002
0003
0004
0005 #ifndef __DEVCOREDUMP_H
0006 #define __DEVCOREDUMP_H
0007
0008 #include <linux/device.h>
0009 #include <linux/module.h>
0010 #include <linux/vmalloc.h>
0011
0012 #include <linux/scatterlist.h>
0013 #include <linux/slab.h>
0014
0015
0016
0017
0018
0019
0020
0021
0022 static inline void _devcd_free_sgtable(struct scatterlist *table)
0023 {
0024 int i;
0025 struct page *page;
0026 struct scatterlist *iter;
0027 struct scatterlist *delete_iter;
0028
0029
0030 iter = table;
0031 for_each_sg(table, iter, sg_nents(table), i) {
0032 page = sg_page(iter);
0033 if (page)
0034 __free_page(page);
0035 }
0036
0037
0038 iter = table;
0039 delete_iter = table;
0040 while (!sg_is_last(iter)) {
0041 iter++;
0042 if (sg_is_chain(iter)) {
0043 iter = sg_chain_ptr(iter);
0044 kfree(delete_iter);
0045 delete_iter = iter;
0046 }
0047 }
0048
0049
0050 kfree(delete_iter);
0051 }
0052
0053
0054 #ifdef CONFIG_DEV_COREDUMP
0055 void dev_coredumpv(struct device *dev, void *data, size_t datalen,
0056 gfp_t gfp);
0057
0058 void dev_coredumpm(struct device *dev, struct module *owner,
0059 void *data, size_t datalen, gfp_t gfp,
0060 ssize_t (*read)(char *buffer, loff_t offset, size_t count,
0061 void *data, size_t datalen),
0062 void (*free)(void *data));
0063
0064 void dev_coredumpsg(struct device *dev, struct scatterlist *table,
0065 size_t datalen, gfp_t gfp);
0066 #else
0067 static inline void dev_coredumpv(struct device *dev, void *data,
0068 size_t datalen, gfp_t gfp)
0069 {
0070 vfree(data);
0071 }
0072
0073 static inline void
0074 dev_coredumpm(struct device *dev, struct module *owner,
0075 void *data, size_t datalen, gfp_t gfp,
0076 ssize_t (*read)(char *buffer, loff_t offset, size_t count,
0077 void *data, size_t datalen),
0078 void (*free)(void *data))
0079 {
0080 free(data);
0081 }
0082
0083 static inline void dev_coredumpsg(struct device *dev, struct scatterlist *table,
0084 size_t datalen, gfp_t gfp)
0085 {
0086 _devcd_free_sgtable(table);
0087 }
0088 #endif
0089
0090 #endif