]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/common/siano/smsdvb-debugfs.c
vfs: do bulk POLL* -> EPOLL* replacement
[mirror_ubuntu-jammy-kernel.git] / drivers / media / common / siano / smsdvb-debugfs.c
CommitLineData
1e6f57b2
MCC
1// SPDX-License-Identifier: GPL-2.0+
2//
3// Copyright(c) 2013 Mauro Carvalho Chehab
503efe5c 4
5e022d1a 5#include "smscoreapi.h"
503efe5c
MCC
6
7#include <linux/module.h>
8#include <linux/slab.h>
9#include <linux/init.h>
10#include <linux/debugfs.h>
11#include <linux/spinlock.h>
12#include <linux/usb.h>
13
fada1935
MCC
14#include <media/dmxdev.h>
15#include <media/dvbdev.h>
16#include <media/dvb_demux.h>
17#include <media/dvb_frontend.h>
503efe5c 18
503efe5c
MCC
19#include "smsdvb.h"
20
21static struct dentry *smsdvb_debugfs_usb_root;
22
23struct smsdvb_debugfs {
24 struct kref refcount;
25 spinlock_t lock;
26
27 char stats_data[PAGE_SIZE];
28 unsigned stats_count;
29 bool stats_was_read;
30
31 wait_queue_head_t stats_queue;
32};
33
2bf0f93e 34static void smsdvb_print_dvb_stats(struct smsdvb_debugfs *debug_data,
cf0e9cfc 35 struct sms_stats *p)
503efe5c
MCC
36{
37 int n = 0;
38 char *buf;
39
40 spin_lock(&debug_data->lock);
41 if (debug_data->stats_count) {
42 spin_unlock(&debug_data->lock);
43 return;
44 }
45
46 buf = debug_data->stats_data;
47
48 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 49 "is_rf_locked = %d\n", p->is_rf_locked);
503efe5c 50 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 51 "is_demod_locked = %d\n", p->is_demod_locked);
503efe5c 52 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 53 "is_external_lna_on = %d\n", p->is_external_lna_on);
503efe5c
MCC
54 n += snprintf(&buf[n], PAGE_SIZE - n,
55 "SNR = %d\n", p->SNR);
56 n += snprintf(&buf[n], PAGE_SIZE - n,
28a59df4 57 "ber = %d\n", p->ber);
503efe5c
MCC
58 n += snprintf(&buf[n], PAGE_SIZE - n,
59 "FIB_CRC = %d\n", p->FIB_CRC);
60 n += snprintf(&buf[n], PAGE_SIZE - n,
28a59df4 61 "ts_per = %d\n", p->ts_per);
503efe5c
MCC
62 n += snprintf(&buf[n], PAGE_SIZE - n,
63 "MFER = %d\n", p->MFER);
64 n += snprintf(&buf[n], PAGE_SIZE - n,
65 "RSSI = %d\n", p->RSSI);
66 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 67 "in_band_pwr = %d\n", p->in_band_pwr);
503efe5c 68 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 69 "carrier_offset = %d\n", p->carrier_offset);
503efe5c 70 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 71 "modem_state = %d\n", p->modem_state);
503efe5c 72 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 73 "frequency = %d\n", p->frequency);
503efe5c 74 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 75 "bandwidth = %d\n", p->bandwidth);
503efe5c 76 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 77 "transmission_mode = %d\n", p->transmission_mode);
503efe5c 78 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 79 "modem_state = %d\n", p->modem_state);
503efe5c 80 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 81 "guard_interval = %d\n", p->guard_interval);
503efe5c 82 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 83 "code_rate = %d\n", p->code_rate);
503efe5c 84 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 85 "lp_code_rate = %d\n", p->lp_code_rate);
503efe5c 86 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 87 "hierarchy = %d\n", p->hierarchy);
503efe5c 88 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 89 "constellation = %d\n", p->constellation);
503efe5c 90 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 91 "burst_size = %d\n", p->burst_size);
503efe5c 92 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 93 "burst_duration = %d\n", p->burst_duration);
503efe5c 94 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 95 "burst_cycle_time = %d\n", p->burst_cycle_time);
503efe5c 96 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 97 "calc_burst_cycle_time = %d\n",
05ad412a 98 p->calc_burst_cycle_time);
503efe5c 99 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 100 "num_of_rows = %d\n", p->num_of_rows);
503efe5c 101 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 102 "num_of_padd_cols = %d\n", p->num_of_padd_cols);
503efe5c 103 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 104 "num_of_punct_cols = %d\n", p->num_of_punct_cols);
503efe5c 105 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 106 "error_ts_packets = %d\n", p->error_ts_packets);
503efe5c 107 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 108 "total_ts_packets = %d\n", p->total_ts_packets);
503efe5c 109 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 110 "num_of_valid_mpe_tlbs = %d\n", p->num_of_valid_mpe_tlbs);
503efe5c 111 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 112 "num_of_invalid_mpe_tlbs = %d\n", p->num_of_invalid_mpe_tlbs);
503efe5c 113 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 114 "num_of_corrected_mpe_tlbs = %d\n", p->num_of_corrected_mpe_tlbs);
503efe5c 115 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 116 "ber_error_count = %d\n", p->ber_error_count);
503efe5c 117 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 118 "ber_bit_count = %d\n", p->ber_bit_count);
503efe5c 119 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 120 "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
503efe5c 121 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 122 "pre_ber = %d\n", p->pre_ber);
503efe5c 123 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 124 "cell_id = %d\n", p->cell_id);
503efe5c 125 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 126 "dvbh_srv_ind_hp = %d\n", p->dvbh_srv_ind_hp);
503efe5c 127 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 128 "dvbh_srv_ind_lp = %d\n", p->dvbh_srv_ind_lp);
503efe5c 129 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 130 "num_mpe_received = %d\n", p->num_mpe_received);
503efe5c
MCC
131
132 debug_data->stats_count = n;
133 spin_unlock(&debug_data->lock);
134 wake_up(&debug_data->stats_queue);
135}
136
2bf0f93e 137static void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data,
cf0e9cfc 138 struct sms_isdbt_stats *p)
503efe5c
MCC
139{
140 int i, n = 0;
141 char *buf;
142
143 spin_lock(&debug_data->lock);
144 if (debug_data->stats_count) {
145 spin_unlock(&debug_data->lock);
146 return;
147 }
148
149 buf = debug_data->stats_data;
150
4cce1f4e 151 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 152 "statistics_type = %d\t", p->statistics_type);
4cce1f4e 153 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 154 "full_size = %d\n", p->full_size);
4cce1f4e 155
503efe5c 156 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 157 "is_rf_locked = %d\t\t", p->is_rf_locked);
503efe5c 158 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 159 "is_demod_locked = %d\t", p->is_demod_locked);
503efe5c 160 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 161 "is_external_lna_on = %d\n", p->is_external_lna_on);
503efe5c
MCC
162 n += snprintf(&buf[n], PAGE_SIZE - n,
163 "SNR = %d dB\t\t", p->SNR);
164 n += snprintf(&buf[n], PAGE_SIZE - n,
165 "RSSI = %d dBm\t\t", p->RSSI);
166 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 167 "in_band_pwr = %d dBm\n", p->in_band_pwr);
503efe5c 168 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 169 "carrier_offset = %d\t", p->carrier_offset);
503efe5c 170 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 171 "bandwidth = %d\t\t", p->bandwidth);
503efe5c 172 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 173 "frequency = %d Hz\n", p->frequency);
503efe5c 174 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 175 "transmission_mode = %d\t", p->transmission_mode);
503efe5c 176 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 177 "modem_state = %d\t\t", p->modem_state);
503efe5c 178 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 179 "guard_interval = %d\n", p->guard_interval);
503efe5c 180 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 181 "system_type = %d\t\t", p->system_type);
503efe5c 182 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 183 "partial_reception = %d\t", p->partial_reception);
503efe5c 184 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 185 "num_of_layers = %d\n", p->num_of_layers);
503efe5c 186 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 187 "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
503efe5c
MCC
188
189 for (i = 0; i < 3; i++) {
28a59df4
MCC
190 if (p->layer_info[i].number_of_segments < 1 ||
191 p->layer_info[i].number_of_segments > 13)
503efe5c
MCC
192 continue;
193
194 n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
dfef84fc 195 n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
28a59df4 196 p->layer_info[i].code_rate);
dfef84fc 197 n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
28a59df4
MCC
198 p->layer_info[i].constellation);
199 n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
200 p->layer_info[i].ber);
dfef84fc 201 n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
28a59df4 202 p->layer_info[i].ber_error_count);
dfef84fc 203 n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
28a59df4 204 p->layer_info[i].ber_bit_count);
dfef84fc 205 n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
28a59df4
MCC
206 p->layer_info[i].pre_ber);
207 n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
208 p->layer_info[i].ts_per);
dfef84fc 209 n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
28a59df4 210 p->layer_info[i].error_ts_packets);
dfef84fc 211 n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
28a59df4 212 p->layer_info[i].total_ts_packets);
dfef84fc 213 n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
28a59df4 214 p->layer_info[i].ti_ldepth_i);
503efe5c 215 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 216 "\tnumber_of_segments = %d\t",
28a59df4 217 p->layer_info[i].number_of_segments);
dfef84fc 218 n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
28a59df4 219 p->layer_info[i].tmcc_errors);
503efe5c
MCC
220 }
221
222 debug_data->stats_count = n;
223 spin_unlock(&debug_data->lock);
224 wake_up(&debug_data->stats_queue);
225}
226
2bf0f93e 227static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data,
cf0e9cfc 228 struct sms_isdbt_stats_ex *p)
503efe5c
MCC
229{
230 int i, n = 0;
231 char *buf;
232
233 spin_lock(&debug_data->lock);
234 if (debug_data->stats_count) {
235 spin_unlock(&debug_data->lock);
236 return;
237 }
238
239 buf = debug_data->stats_data;
240
4cce1f4e 241 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 242 "statistics_type = %d\t", p->statistics_type);
4cce1f4e 243 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 244 "full_size = %d\n", p->full_size);
4cce1f4e 245
503efe5c 246 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 247 "is_rf_locked = %d\t\t", p->is_rf_locked);
503efe5c 248 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 249 "is_demod_locked = %d\t", p->is_demod_locked);
503efe5c 250 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 251 "is_external_lna_on = %d\n", p->is_external_lna_on);
503efe5c
MCC
252 n += snprintf(&buf[n], PAGE_SIZE - n,
253 "SNR = %d dB\t\t", p->SNR);
254 n += snprintf(&buf[n], PAGE_SIZE - n,
255 "RSSI = %d dBm\t\t", p->RSSI);
256 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 257 "in_band_pwr = %d dBm\n", p->in_band_pwr);
503efe5c 258 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 259 "carrier_offset = %d\t", p->carrier_offset);
503efe5c 260 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 261 "bandwidth = %d\t\t", p->bandwidth);
503efe5c 262 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 263 "frequency = %d Hz\n", p->frequency);
503efe5c 264 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 265 "transmission_mode = %d\t", p->transmission_mode);
503efe5c 266 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 267 "modem_state = %d\t\t", p->modem_state);
503efe5c 268 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 269 "guard_interval = %d\n", p->guard_interval);
503efe5c 270 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 271 "system_type = %d\t\t", p->system_type);
503efe5c 272 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 273 "partial_reception = %d\t", p->partial_reception);
503efe5c 274 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc
MCC
275 "num_of_layers = %d\n", p->num_of_layers);
276 n += snprintf(&buf[n], PAGE_SIZE - n, "segment_number = %d\t",
277 p->segment_number);
278 n += snprintf(&buf[n], PAGE_SIZE - n, "tune_bw = %d\n",
279 p->tune_bw);
503efe5c
MCC
280
281 for (i = 0; i < 3; i++) {
28a59df4
MCC
282 if (p->layer_info[i].number_of_segments < 1 ||
283 p->layer_info[i].number_of_segments > 13)
503efe5c
MCC
284 continue;
285
286 n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
dfef84fc 287 n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
28a59df4 288 p->layer_info[i].code_rate);
dfef84fc 289 n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
28a59df4
MCC
290 p->layer_info[i].constellation);
291 n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
292 p->layer_info[i].ber);
dfef84fc 293 n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
28a59df4 294 p->layer_info[i].ber_error_count);
dfef84fc 295 n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
28a59df4 296 p->layer_info[i].ber_bit_count);
dfef84fc 297 n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
28a59df4
MCC
298 p->layer_info[i].pre_ber);
299 n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
300 p->layer_info[i].ts_per);
dfef84fc 301 n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
28a59df4 302 p->layer_info[i].error_ts_packets);
dfef84fc 303 n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
28a59df4 304 p->layer_info[i].total_ts_packets);
dfef84fc 305 n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
28a59df4 306 p->layer_info[i].ti_ldepth_i);
503efe5c 307 n += snprintf(&buf[n], PAGE_SIZE - n,
dfef84fc 308 "\tnumber_of_segments = %d\t",
28a59df4 309 p->layer_info[i].number_of_segments);
dfef84fc 310 n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
28a59df4 311 p->layer_info[i].tmcc_errors);
503efe5c
MCC
312 }
313
314
315 debug_data->stats_count = n;
316 spin_unlock(&debug_data->lock);
317
318 wake_up(&debug_data->stats_queue);
319}
320
321static int smsdvb_stats_open(struct inode *inode, struct file *file)
322{
323 struct smsdvb_client_t *client = inode->i_private;
324 struct smsdvb_debugfs *debug_data = client->debug_data;
325
326 kref_get(&debug_data->refcount);
327
328 spin_lock(&debug_data->lock);
329 debug_data->stats_count = 0;
330 debug_data->stats_was_read = false;
331 spin_unlock(&debug_data->lock);
332
333 file->private_data = debug_data;
334
335 return 0;
336}
337
6a28bd94
MCC
338static void smsdvb_debugfs_data_release(struct kref *ref)
339{
340 struct smsdvb_debugfs *debug_data;
341
342 debug_data = container_of(ref, struct smsdvb_debugfs, refcount);
343 kfree(debug_data);
344}
345
503efe5c
MCC
346static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data)
347{
348 int rc = 1;
349
350 spin_lock(&debug_data->lock);
351
352 if (debug_data->stats_was_read)
353 goto exit;
354
355 rc = debug_data->stats_count;
356
357exit:
358 spin_unlock(&debug_data->lock);
359 return rc;
360}
361
c23e0cb8 362static __poll_t smsdvb_stats_poll(struct file *file, poll_table *wait)
503efe5c 363{
503efe5c 364 struct smsdvb_debugfs *debug_data = file->private_data;
6a28bd94 365 int rc;
503efe5c 366
6a28bd94 367 kref_get(&debug_data->refcount);
503efe5c 368
6a28bd94
MCC
369 poll_wait(file, &debug_data->stats_queue, wait);
370
371 rc = smsdvb_stats_wait_read(debug_data);
6a28bd94 372 kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
503efe5c 373
a9a08845 374 return rc > 0 ? EPOLLIN | EPOLLRDNORM : 0;
503efe5c
MCC
375}
376
6a28bd94
MCC
377static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
378 size_t nbytes, loff_t *ppos)
503efe5c 379{
6a28bd94
MCC
380 int rc = 0, len;
381 struct smsdvb_debugfs *debug_data = file->private_data;
503efe5c 382
6a28bd94
MCC
383 kref_get(&debug_data->refcount);
384
385 if (file->f_flags & O_NONBLOCK) {
386 rc = smsdvb_stats_wait_read(debug_data);
387 if (!rc) {
388 rc = -EWOULDBLOCK;
389 goto ret;
390 }
391 } else {
392 rc = wait_event_interruptible(debug_data->stats_queue,
393 smsdvb_stats_wait_read(debug_data));
394 if (rc < 0)
395 goto ret;
396 }
397
398 if (debug_data->stats_was_read) {
399 rc = 0; /* EOF */
400 goto ret;
401 }
402
403 len = debug_data->stats_count - *ppos;
404 if (len >= 0)
405 rc = simple_read_from_buffer(user_buf, nbytes, ppos,
406 debug_data->stats_data, len);
407 else
408 rc = 0;
409
410 if (*ppos >= debug_data->stats_count) {
411 spin_lock(&debug_data->lock);
412 debug_data->stats_was_read = true;
413 spin_unlock(&debug_data->lock);
414 }
415ret:
416 kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
417 return rc;
503efe5c
MCC
418}
419
420static int smsdvb_stats_release(struct inode *inode, struct file *file)
421{
422 struct smsdvb_debugfs *debug_data = file->private_data;
423
424 spin_lock(&debug_data->lock);
6a28bd94 425 debug_data->stats_was_read = true; /* return EOF to read() */
503efe5c
MCC
426 spin_unlock(&debug_data->lock);
427 wake_up_interruptible_sync(&debug_data->stats_queue);
428
429 kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
430 file->private_data = NULL;
431
432 return 0;
433}
434
435static const struct file_operations debugfs_stats_ops = {
436 .open = smsdvb_stats_open,
6a28bd94 437 .poll = smsdvb_stats_poll,
503efe5c
MCC
438 .read = smsdvb_stats_read,
439 .release = smsdvb_stats_release,
440 .llseek = generic_file_llseek,
441};
442
443/*
444 * Functions used by smsdvb, in order to create the interfaces
445 */
446
447int smsdvb_debugfs_create(struct smsdvb_client_t *client)
448{
449 struct smscore_device_t *coredev = client->coredev;
450 struct dentry *d;
451 struct smsdvb_debugfs *debug_data;
452
453 if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device)
454 return -ENODEV;
455
456 client->debugfs = debugfs_create_dir(coredev->devpath,
457 smsdvb_debugfs_usb_root);
458 if (IS_ERR_OR_NULL(client->debugfs)) {
459 pr_info("Unable to create debugfs %s directory.\n",
460 coredev->devpath);
461 return -ENODEV;
462 }
463
464 d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
465 client, &debugfs_stats_ops);
466 if (!d) {
467 debugfs_remove(client->debugfs);
468 return -ENOMEM;
469 }
470
471 debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL);
472 if (!debug_data)
473 return -ENOMEM;
474
475 client->debug_data = debug_data;
476 client->prt_dvb_stats = smsdvb_print_dvb_stats;
477 client->prt_isdb_stats = smsdvb_print_isdb_stats;
478 client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex;
479
480 init_waitqueue_head(&debug_data->stats_queue);
481 spin_lock_init(&debug_data->lock);
482 kref_init(&debug_data->refcount);
483
484 return 0;
485}
486
487void smsdvb_debugfs_release(struct smsdvb_client_t *client)
488{
489 if (!client->debugfs)
490 return;
491
503efe5c
MCC
492 client->prt_dvb_stats = NULL;
493 client->prt_isdb_stats = NULL;
494 client->prt_isdb_stats_ex = NULL;
495
496 debugfs_remove_recursive(client->debugfs);
497 kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release);
498
499 client->debug_data = NULL;
500 client->debugfs = NULL;
501}
502
503int smsdvb_debugfs_register(void)
504{
505 struct dentry *d;
506
507 /*
508 * FIXME: This was written to debug Siano USB devices. So, it creates
509 * the debugfs node under <debugfs>/usb.
510 * A similar logic would be needed for Siano sdio devices, but, in that
511 * case, usb_debug_root is not a good choice.
512 *
513 * Perhaps the right fix here would be to create another sysfs root
514 * node for sdio-based boards, but this may need some logic at sdio
515 * subsystem.
516 */
517 d = debugfs_create_dir("smsdvb", usb_debug_root);
518 if (IS_ERR_OR_NULL(d)) {
5ed0a2c7 519 pr_err("Couldn't create sysfs node for smsdvb\n");
503efe5c
MCC
520 return PTR_ERR(d);
521 } else {
522 smsdvb_debugfs_usb_root = d;
523 }
524 return 0;
525}
526
527void smsdvb_debugfs_unregister(void)
528{
05ad412a 529 debugfs_remove_recursive(smsdvb_debugfs_usb_root);
503efe5c
MCC
530 smsdvb_debugfs_usb_root = NULL;
531}