1 /***********************************************************************
3 * Copyright(c) 2013 Mauro Carvalho Chehab
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 ***********************************************************************/
20 #include "smscoreapi.h"
22 #include <linux/module.h>
23 #include <linux/slab.h>
24 #include <linux/init.h>
25 #include <linux/debugfs.h>
26 #include <linux/spinlock.h>
27 #include <linux/usb.h>
31 #include "dvb_demux.h"
32 #include "dvb_frontend.h"
36 static struct dentry
*smsdvb_debugfs_usb_root
;
38 struct smsdvb_debugfs
{
42 char stats_data
[PAGE_SIZE
];
46 wait_queue_head_t stats_queue
;
49 static void smsdvb_print_dvb_stats(struct smsdvb_debugfs
*debug_data
,
55 spin_lock(&debug_data
->lock
);
56 if (debug_data
->stats_count
) {
57 spin_unlock(&debug_data
->lock
);
61 buf
= debug_data
->stats_data
;
63 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
64 "is_rf_locked = %d\n", p
->is_rf_locked
);
65 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
66 "is_demod_locked = %d\n", p
->is_demod_locked
);
67 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
68 "is_external_lna_on = %d\n", p
->is_external_lna_on
);
69 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
70 "SNR = %d\n", p
->SNR
);
71 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
72 "ber = %d\n", p
->ber
);
73 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
74 "FIB_CRC = %d\n", p
->FIB_CRC
);
75 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
76 "ts_per = %d\n", p
->ts_per
);
77 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
78 "MFER = %d\n", p
->MFER
);
79 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
80 "RSSI = %d\n", p
->RSSI
);
81 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
82 "in_band_pwr = %d\n", p
->in_band_pwr
);
83 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
84 "carrier_offset = %d\n", p
->carrier_offset
);
85 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
86 "modem_state = %d\n", p
->modem_state
);
87 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
88 "frequency = %d\n", p
->frequency
);
89 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
90 "bandwidth = %d\n", p
->bandwidth
);
91 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
92 "transmission_mode = %d\n", p
->transmission_mode
);
93 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
94 "modem_state = %d\n", p
->modem_state
);
95 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
96 "guard_interval = %d\n", p
->guard_interval
);
97 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
98 "code_rate = %d\n", p
->code_rate
);
99 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
100 "lp_code_rate = %d\n", p
->lp_code_rate
);
101 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
102 "hierarchy = %d\n", p
->hierarchy
);
103 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
104 "constellation = %d\n", p
->constellation
);
105 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
106 "burst_size = %d\n", p
->burst_size
);
107 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
108 "burst_duration = %d\n", p
->burst_duration
);
109 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
110 "burst_cycle_time = %d\n", p
->burst_cycle_time
);
111 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
112 "calc_burst_cycle_time = %d\n",
113 p
->calc_burst_cycle_time
);
114 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
115 "num_of_rows = %d\n", p
->num_of_rows
);
116 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
117 "num_of_padd_cols = %d\n", p
->num_of_padd_cols
);
118 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
119 "num_of_punct_cols = %d\n", p
->num_of_punct_cols
);
120 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
121 "error_ts_packets = %d\n", p
->error_ts_packets
);
122 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
123 "total_ts_packets = %d\n", p
->total_ts_packets
);
124 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
125 "num_of_valid_mpe_tlbs = %d\n", p
->num_of_valid_mpe_tlbs
);
126 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
127 "num_of_invalid_mpe_tlbs = %d\n", p
->num_of_invalid_mpe_tlbs
);
128 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
129 "num_of_corrected_mpe_tlbs = %d\n", p
->num_of_corrected_mpe_tlbs
);
130 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
131 "ber_error_count = %d\n", p
->ber_error_count
);
132 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
133 "ber_bit_count = %d\n", p
->ber_bit_count
);
134 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
135 "sms_to_host_tx_errors = %d\n", p
->sms_to_host_tx_errors
);
136 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
137 "pre_ber = %d\n", p
->pre_ber
);
138 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
139 "cell_id = %d\n", p
->cell_id
);
140 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
141 "dvbh_srv_ind_hp = %d\n", p
->dvbh_srv_ind_hp
);
142 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
143 "dvbh_srv_ind_lp = %d\n", p
->dvbh_srv_ind_lp
);
144 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
145 "num_mpe_received = %d\n", p
->num_mpe_received
);
147 debug_data
->stats_count
= n
;
148 spin_unlock(&debug_data
->lock
);
149 wake_up(&debug_data
->stats_queue
);
152 static void smsdvb_print_isdb_stats(struct smsdvb_debugfs
*debug_data
,
153 struct sms_isdbt_stats
*p
)
158 spin_lock(&debug_data
->lock
);
159 if (debug_data
->stats_count
) {
160 spin_unlock(&debug_data
->lock
);
164 buf
= debug_data
->stats_data
;
166 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
167 "statistics_type = %d\t", p
->statistics_type
);
168 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
169 "full_size = %d\n", p
->full_size
);
171 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
172 "is_rf_locked = %d\t\t", p
->is_rf_locked
);
173 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
174 "is_demod_locked = %d\t", p
->is_demod_locked
);
175 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
176 "is_external_lna_on = %d\n", p
->is_external_lna_on
);
177 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
178 "SNR = %d dB\t\t", p
->SNR
);
179 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
180 "RSSI = %d dBm\t\t", p
->RSSI
);
181 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
182 "in_band_pwr = %d dBm\n", p
->in_band_pwr
);
183 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
184 "carrier_offset = %d\t", p
->carrier_offset
);
185 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
186 "bandwidth = %d\t\t", p
->bandwidth
);
187 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
188 "frequency = %d Hz\n", p
->frequency
);
189 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
190 "transmission_mode = %d\t", p
->transmission_mode
);
191 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
192 "modem_state = %d\t\t", p
->modem_state
);
193 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
194 "guard_interval = %d\n", p
->guard_interval
);
195 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
196 "system_type = %d\t\t", p
->system_type
);
197 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
198 "partial_reception = %d\t", p
->partial_reception
);
199 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
200 "num_of_layers = %d\n", p
->num_of_layers
);
201 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
202 "sms_to_host_tx_errors = %d\n", p
->sms_to_host_tx_errors
);
204 for (i
= 0; i
< 3; i
++) {
205 if (p
->layer_info
[i
].number_of_segments
< 1 ||
206 p
->layer_info
[i
].number_of_segments
> 13)
209 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\nLayer %d\n", i
);
210 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tcode_rate = %d\t",
211 p
->layer_info
[i
].code_rate
);
212 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "constellation = %d\n",
213 p
->layer_info
[i
].constellation
);
214 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tber = %-5d\t",
215 p
->layer_info
[i
].ber
);
216 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tber_error_count = %-5d\t",
217 p
->layer_info
[i
].ber_error_count
);
218 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "ber_bit_count = %-5d\n",
219 p
->layer_info
[i
].ber_bit_count
);
220 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tpre_ber = %-5d\t",
221 p
->layer_info
[i
].pre_ber
);
222 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tts_per = %-5d\n",
223 p
->layer_info
[i
].ts_per
);
224 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\terror_ts_packets = %-5d\t",
225 p
->layer_info
[i
].error_ts_packets
);
226 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "total_ts_packets = %-5d\t",
227 p
->layer_info
[i
].total_ts_packets
);
228 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "ti_ldepth_i = %d\n",
229 p
->layer_info
[i
].ti_ldepth_i
);
230 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
231 "\tnumber_of_segments = %d\t",
232 p
->layer_info
[i
].number_of_segments
);
233 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "tmcc_errors = %d\n",
234 p
->layer_info
[i
].tmcc_errors
);
237 debug_data
->stats_count
= n
;
238 spin_unlock(&debug_data
->lock
);
239 wake_up(&debug_data
->stats_queue
);
242 static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs
*debug_data
,
243 struct sms_isdbt_stats_ex
*p
)
248 spin_lock(&debug_data
->lock
);
249 if (debug_data
->stats_count
) {
250 spin_unlock(&debug_data
->lock
);
254 buf
= debug_data
->stats_data
;
256 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
257 "statistics_type = %d\t", p
->statistics_type
);
258 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
259 "full_size = %d\n", p
->full_size
);
261 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
262 "is_rf_locked = %d\t\t", p
->is_rf_locked
);
263 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
264 "is_demod_locked = %d\t", p
->is_demod_locked
);
265 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
266 "is_external_lna_on = %d\n", p
->is_external_lna_on
);
267 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
268 "SNR = %d dB\t\t", p
->SNR
);
269 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
270 "RSSI = %d dBm\t\t", p
->RSSI
);
271 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
272 "in_band_pwr = %d dBm\n", p
->in_band_pwr
);
273 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
274 "carrier_offset = %d\t", p
->carrier_offset
);
275 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
276 "bandwidth = %d\t\t", p
->bandwidth
);
277 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
278 "frequency = %d Hz\n", p
->frequency
);
279 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
280 "transmission_mode = %d\t", p
->transmission_mode
);
281 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
282 "modem_state = %d\t\t", p
->modem_state
);
283 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
284 "guard_interval = %d\n", p
->guard_interval
);
285 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
286 "system_type = %d\t\t", p
->system_type
);
287 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
288 "partial_reception = %d\t", p
->partial_reception
);
289 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
290 "num_of_layers = %d\n", p
->num_of_layers
);
291 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "segment_number = %d\t",
293 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "tune_bw = %d\n",
296 for (i
= 0; i
< 3; i
++) {
297 if (p
->layer_info
[i
].number_of_segments
< 1 ||
298 p
->layer_info
[i
].number_of_segments
> 13)
301 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\nLayer %d\n", i
);
302 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tcode_rate = %d\t",
303 p
->layer_info
[i
].code_rate
);
304 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "constellation = %d\n",
305 p
->layer_info
[i
].constellation
);
306 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tber = %-5d\t",
307 p
->layer_info
[i
].ber
);
308 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tber_error_count = %-5d\t",
309 p
->layer_info
[i
].ber_error_count
);
310 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "ber_bit_count = %-5d\n",
311 p
->layer_info
[i
].ber_bit_count
);
312 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tpre_ber = %-5d\t",
313 p
->layer_info
[i
].pre_ber
);
314 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\tts_per = %-5d\n",
315 p
->layer_info
[i
].ts_per
);
316 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "\terror_ts_packets = %-5d\t",
317 p
->layer_info
[i
].error_ts_packets
);
318 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "total_ts_packets = %-5d\t",
319 p
->layer_info
[i
].total_ts_packets
);
320 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "ti_ldepth_i = %d\n",
321 p
->layer_info
[i
].ti_ldepth_i
);
322 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
,
323 "\tnumber_of_segments = %d\t",
324 p
->layer_info
[i
].number_of_segments
);
325 n
+= snprintf(&buf
[n
], PAGE_SIZE
- n
, "tmcc_errors = %d\n",
326 p
->layer_info
[i
].tmcc_errors
);
330 debug_data
->stats_count
= n
;
331 spin_unlock(&debug_data
->lock
);
333 wake_up(&debug_data
->stats_queue
);
336 static int smsdvb_stats_open(struct inode
*inode
, struct file
*file
)
338 struct smsdvb_client_t
*client
= inode
->i_private
;
339 struct smsdvb_debugfs
*debug_data
= client
->debug_data
;
341 kref_get(&debug_data
->refcount
);
343 spin_lock(&debug_data
->lock
);
344 debug_data
->stats_count
= 0;
345 debug_data
->stats_was_read
= false;
346 spin_unlock(&debug_data
->lock
);
348 file
->private_data
= debug_data
;
353 static void smsdvb_debugfs_data_release(struct kref
*ref
)
355 struct smsdvb_debugfs
*debug_data
;
357 debug_data
= container_of(ref
, struct smsdvb_debugfs
, refcount
);
361 static int smsdvb_stats_wait_read(struct smsdvb_debugfs
*debug_data
)
365 spin_lock(&debug_data
->lock
);
367 if (debug_data
->stats_was_read
)
370 rc
= debug_data
->stats_count
;
373 spin_unlock(&debug_data
->lock
);
377 static unsigned int smsdvb_stats_poll(struct file
*file
, poll_table
*wait
)
379 struct smsdvb_debugfs
*debug_data
= file
->private_data
;
382 kref_get(&debug_data
->refcount
);
384 poll_wait(file
, &debug_data
->stats_queue
, wait
);
386 rc
= smsdvb_stats_wait_read(debug_data
);
388 rc
= POLLIN
| POLLRDNORM
;
390 kref_put(&debug_data
->refcount
, smsdvb_debugfs_data_release
);
395 static ssize_t
smsdvb_stats_read(struct file
*file
, char __user
*user_buf
,
396 size_t nbytes
, loff_t
*ppos
)
399 struct smsdvb_debugfs
*debug_data
= file
->private_data
;
401 kref_get(&debug_data
->refcount
);
403 if (file
->f_flags
& O_NONBLOCK
) {
404 rc
= smsdvb_stats_wait_read(debug_data
);
410 rc
= wait_event_interruptible(debug_data
->stats_queue
,
411 smsdvb_stats_wait_read(debug_data
));
416 if (debug_data
->stats_was_read
) {
421 len
= debug_data
->stats_count
- *ppos
;
423 rc
= simple_read_from_buffer(user_buf
, nbytes
, ppos
,
424 debug_data
->stats_data
, len
);
428 if (*ppos
>= debug_data
->stats_count
) {
429 spin_lock(&debug_data
->lock
);
430 debug_data
->stats_was_read
= true;
431 spin_unlock(&debug_data
->lock
);
434 kref_put(&debug_data
->refcount
, smsdvb_debugfs_data_release
);
438 static int smsdvb_stats_release(struct inode
*inode
, struct file
*file
)
440 struct smsdvb_debugfs
*debug_data
= file
->private_data
;
442 spin_lock(&debug_data
->lock
);
443 debug_data
->stats_was_read
= true; /* return EOF to read() */
444 spin_unlock(&debug_data
->lock
);
445 wake_up_interruptible_sync(&debug_data
->stats_queue
);
447 kref_put(&debug_data
->refcount
, smsdvb_debugfs_data_release
);
448 file
->private_data
= NULL
;
453 static const struct file_operations debugfs_stats_ops
= {
454 .open
= smsdvb_stats_open
,
455 .poll
= smsdvb_stats_poll
,
456 .read
= smsdvb_stats_read
,
457 .release
= smsdvb_stats_release
,
458 .llseek
= generic_file_llseek
,
462 * Functions used by smsdvb, in order to create the interfaces
465 int smsdvb_debugfs_create(struct smsdvb_client_t
*client
)
467 struct smscore_device_t
*coredev
= client
->coredev
;
469 struct smsdvb_debugfs
*debug_data
;
471 if (!smsdvb_debugfs_usb_root
|| !coredev
->is_usb_device
)
474 client
->debugfs
= debugfs_create_dir(coredev
->devpath
,
475 smsdvb_debugfs_usb_root
);
476 if (IS_ERR_OR_NULL(client
->debugfs
)) {
477 pr_info("Unable to create debugfs %s directory.\n",
482 d
= debugfs_create_file("stats", S_IRUGO
| S_IWUSR
, client
->debugfs
,
483 client
, &debugfs_stats_ops
);
485 debugfs_remove(client
->debugfs
);
489 debug_data
= kzalloc(sizeof(*client
->debug_data
), GFP_KERNEL
);
493 client
->debug_data
= debug_data
;
494 client
->prt_dvb_stats
= smsdvb_print_dvb_stats
;
495 client
->prt_isdb_stats
= smsdvb_print_isdb_stats
;
496 client
->prt_isdb_stats_ex
= smsdvb_print_isdb_stats_ex
;
498 init_waitqueue_head(&debug_data
->stats_queue
);
499 spin_lock_init(&debug_data
->lock
);
500 kref_init(&debug_data
->refcount
);
505 void smsdvb_debugfs_release(struct smsdvb_client_t
*client
)
507 if (!client
->debugfs
)
510 client
->prt_dvb_stats
= NULL
;
511 client
->prt_isdb_stats
= NULL
;
512 client
->prt_isdb_stats_ex
= NULL
;
514 debugfs_remove_recursive(client
->debugfs
);
515 kref_put(&client
->debug_data
->refcount
, smsdvb_debugfs_data_release
);
517 client
->debug_data
= NULL
;
518 client
->debugfs
= NULL
;
521 int smsdvb_debugfs_register(void)
526 * FIXME: This was written to debug Siano USB devices. So, it creates
527 * the debugfs node under <debugfs>/usb.
528 * A similar logic would be needed for Siano sdio devices, but, in that
529 * case, usb_debug_root is not a good choice.
531 * Perhaps the right fix here would be to create another sysfs root
532 * node for sdio-based boards, but this may need some logic at sdio
535 d
= debugfs_create_dir("smsdvb", usb_debug_root
);
536 if (IS_ERR_OR_NULL(d
)) {
537 pr_err("Couldn't create sysfs node for smsdvb\n");
540 smsdvb_debugfs_usb_root
= d
;
545 void smsdvb_debugfs_unregister(void)
547 debugfs_remove_recursive(smsdvb_debugfs_usb_root
);
548 smsdvb_debugfs_usb_root
= NULL
;