1 /*
2  * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: qdf_streamfs
21  * This file provides QDF stream file system APIs
22  */
23 
24 #include <i_qdf_streamfs.h>
25 #include <qdf_trace.h>
26 #include <qdf_streamfs.h>
27 #include <qdf_module.h>
28 
29 /**
30  * qdf_create_buf_file_handler() - Create streamfs buffer file
31  * @filename: base name of files to create, NULL for buffering only
32  * @parent: dentry of parent directory, NULL for root directory
33  * @mode: filemode
34  * @buf: streamfs channel buf
35  * @is_global: pointer to set whether this buf file is global or not.
36  *
37  *  Returns dentry if successful, NULL otherwise.
38  */
39 static qdf_dentry_t
qdf_create_buf_file_handler(const char * filename,qdf_dentry_t parent,uint16_t mode,qdf_streamfs_chan_buf_t buf,int32_t * is_global)40 qdf_create_buf_file_handler(const char *filename, qdf_dentry_t parent,
41 			    uint16_t mode, qdf_streamfs_chan_buf_t buf,
42 			    int32_t *is_global)
43 {
44 	qdf_dentry_t buf_file;
45 	*is_global = 1;
46 	buf_file = qdf_streamfs_create_file(filename, mode, parent, buf);
47 
48 	if (!buf_file)
49 		return NULL;
50 
51 	return buf_file;
52 }
53 
54 /**
55  * qdf_remove_buf_file_handler() - Remove streamfs buffer file
56  *  @dentry:dentry
57  */
qdf_remove_buf_file_handler(qdf_dentry_t dentry)58 static int qdf_remove_buf_file_handler(qdf_dentry_t dentry)
59 {
60 	qdf_streamfs_remove_file(dentry);
61 
62 	return 0;
63 }
64 
65 static struct rchan_callbacks g_qdf_streamfs_cb = {
66 	.create_buf_file = qdf_create_buf_file_handler,
67 	.remove_buf_file = qdf_remove_buf_file_handler,
68 };
69 
70 qdf_dentry_t
qdf_streamfs_create_file(const char * name,uint16_t mode,qdf_dentry_t parent,qdf_streamfs_chan_buf_t buf)71 qdf_streamfs_create_file(const char *name, uint16_t mode,
72 			 qdf_dentry_t parent,
73 			 qdf_streamfs_chan_buf_t buf)
74 {
75 	qdf_dentry_t file = NULL;
76 
77 	if (!name)
78 		return NULL;
79 
80 	file = debugfs_create_file(name, mode,
81 				   (struct dentry *)parent,
82 				   buf, &relay_file_operations);
83 
84 	return file;
85 }
86 
87 qdf_export_symbol(qdf_streamfs_create_file);
88 
89 qdf_streamfs_chan_t
qdf_streamfs_open(const char * base_filename,qdf_dentry_t parent,size_t subbuf_size,size_t n_subbufs,void * private_data)90 qdf_streamfs_open(const char *base_filename, qdf_dentry_t parent,
91 		  size_t subbuf_size, size_t n_subbufs,
92 		  void *private_data)
93 {
94 	qdf_streamfs_chan_t channel_ptr = NULL;
95 
96 	channel_ptr = relay_open(base_filename,
97 				 (struct dentry *)parent,
98 				 subbuf_size, n_subbufs,
99 				 &g_qdf_streamfs_cb,
100 				 private_data);
101 
102 	return channel_ptr;
103 }
104 
105 qdf_export_symbol(qdf_streamfs_open);
106 
qdf_streamfs_close(qdf_streamfs_chan_t chan)107 void qdf_streamfs_close(qdf_streamfs_chan_t chan)
108 {
109 	if (chan)
110 		relay_close(chan);
111 }
112 
113 qdf_export_symbol(qdf_streamfs_close);
114 
qdf_streamfs_flush(qdf_streamfs_chan_t chan)115 void qdf_streamfs_flush(qdf_streamfs_chan_t chan)
116 {
117 	if (chan)
118 		relay_flush(chan);
119 }
120 
121 qdf_export_symbol(qdf_streamfs_flush);
122 
qdf_streamfs_reset(qdf_streamfs_chan_t chan)123 void qdf_streamfs_reset(qdf_streamfs_chan_t chan)
124 {
125 	if (chan)
126 		relay_reset(chan);
127 }
128 
129 qdf_export_symbol(qdf_streamfs_reset);
130 
qdf_streamfs_subbufs_consumed(qdf_streamfs_chan_t chan,unsigned int cpu,size_t consumed)131 void qdf_streamfs_subbufs_consumed(qdf_streamfs_chan_t chan,
132 				   unsigned int cpu,
133 				   size_t consumed)
134 {
135 	if (chan)
136 		relay_subbufs_consumed(chan, cpu, consumed);
137 }
138 
139 qdf_export_symbol(qdf_streamfs_subbufs_consumed);
140 
qdf_streamfs_write(qdf_streamfs_chan_t chan,const void * data,size_t length)141 void qdf_streamfs_write(qdf_streamfs_chan_t chan,
142 			const void *data,
143 			size_t length)
144 {
145 	if (chan)
146 		relay_write(chan, data, length);
147 }
148 
149 qdf_export_symbol(qdf_streamfs_write);
150