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