Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright(c) 2015 Intel Deutschland GmbH
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  * _devcd_free_sgtable - free all the memory of the given scatterlist table
0017  * (i.e. both pages and scatterlist instances)
0018  * NOTE: if two tables allocated and chained using the sg_chain function then
0019  * this function should be called only once on the first table
0020  * @table: pointer to sg_table to free
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     /* free pages */
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     /* then free all chained tables */
0038     iter = table;
0039     delete_iter = table;    /* always points on a head of a 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     /* free the last table */
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 /* CONFIG_DEV_COREDUMP */
0089 
0090 #endif /* __DEVCOREDUMP_H */