Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // Copyright(c) 2013 Mauro Carvalho Chehab
0004 
0005 #include "smscoreapi.h"
0006 
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009 #include <linux/init.h>
0010 #include <linux/debugfs.h>
0011 #include <linux/spinlock.h>
0012 #include <linux/usb.h>
0013 
0014 #include <media/dmxdev.h>
0015 #include <media/dvbdev.h>
0016 #include <media/dvb_demux.h>
0017 #include <media/dvb_frontend.h>
0018 
0019 #include "smsdvb.h"
0020 
0021 static struct dentry *smsdvb_debugfs_usb_root;
0022 
0023 struct smsdvb_debugfs {
0024     struct kref     refcount;
0025     spinlock_t      lock;
0026 
0027     char            stats_data[PAGE_SIZE];
0028     unsigned        stats_count;
0029     bool            stats_was_read;
0030 
0031     wait_queue_head_t   stats_queue;
0032 };
0033 
0034 static void smsdvb_print_dvb_stats(struct smsdvb_debugfs *debug_data,
0035                 struct sms_stats *p)
0036 {
0037     int n = 0;
0038     char *buf;
0039 
0040     spin_lock(&debug_data->lock);
0041     if (debug_data->stats_count) {
0042         spin_unlock(&debug_data->lock);
0043         return;
0044     }
0045 
0046     buf = debug_data->stats_data;
0047 
0048     n += scnprintf(&buf[n], PAGE_SIZE - n,
0049               "is_rf_locked = %d\n", p->is_rf_locked);
0050     n += scnprintf(&buf[n], PAGE_SIZE - n,
0051               "is_demod_locked = %d\n", p->is_demod_locked);
0052     n += scnprintf(&buf[n], PAGE_SIZE - n,
0053               "is_external_lna_on = %d\n", p->is_external_lna_on);
0054     n += scnprintf(&buf[n], PAGE_SIZE - n,
0055               "SNR = %d\n", p->SNR);
0056     n += scnprintf(&buf[n], PAGE_SIZE - n,
0057               "ber = %d\n", p->ber);
0058     n += scnprintf(&buf[n], PAGE_SIZE - n,
0059               "FIB_CRC = %d\n", p->FIB_CRC);
0060     n += scnprintf(&buf[n], PAGE_SIZE - n,
0061               "ts_per = %d\n", p->ts_per);
0062     n += scnprintf(&buf[n], PAGE_SIZE - n,
0063               "MFER = %d\n", p->MFER);
0064     n += scnprintf(&buf[n], PAGE_SIZE - n,
0065               "RSSI = %d\n", p->RSSI);
0066     n += scnprintf(&buf[n], PAGE_SIZE - n,
0067               "in_band_pwr = %d\n", p->in_band_pwr);
0068     n += scnprintf(&buf[n], PAGE_SIZE - n,
0069               "carrier_offset = %d\n", p->carrier_offset);
0070     n += scnprintf(&buf[n], PAGE_SIZE - n,
0071               "modem_state = %d\n", p->modem_state);
0072     n += scnprintf(&buf[n], PAGE_SIZE - n,
0073               "frequency = %d\n", p->frequency);
0074     n += scnprintf(&buf[n], PAGE_SIZE - n,
0075               "bandwidth = %d\n", p->bandwidth);
0076     n += scnprintf(&buf[n], PAGE_SIZE - n,
0077               "transmission_mode = %d\n", p->transmission_mode);
0078     n += scnprintf(&buf[n], PAGE_SIZE - n,
0079               "modem_state = %d\n", p->modem_state);
0080     n += scnprintf(&buf[n], PAGE_SIZE - n,
0081               "guard_interval = %d\n", p->guard_interval);
0082     n += scnprintf(&buf[n], PAGE_SIZE - n,
0083               "code_rate = %d\n", p->code_rate);
0084     n += scnprintf(&buf[n], PAGE_SIZE - n,
0085               "lp_code_rate = %d\n", p->lp_code_rate);
0086     n += scnprintf(&buf[n], PAGE_SIZE - n,
0087               "hierarchy = %d\n", p->hierarchy);
0088     n += scnprintf(&buf[n], PAGE_SIZE - n,
0089               "constellation = %d\n", p->constellation);
0090     n += scnprintf(&buf[n], PAGE_SIZE - n,
0091               "burst_size = %d\n", p->burst_size);
0092     n += scnprintf(&buf[n], PAGE_SIZE - n,
0093               "burst_duration = %d\n", p->burst_duration);
0094     n += scnprintf(&buf[n], PAGE_SIZE - n,
0095               "burst_cycle_time = %d\n", p->burst_cycle_time);
0096     n += scnprintf(&buf[n], PAGE_SIZE - n,
0097               "calc_burst_cycle_time = %d\n",
0098               p->calc_burst_cycle_time);
0099     n += scnprintf(&buf[n], PAGE_SIZE - n,
0100               "num_of_rows = %d\n", p->num_of_rows);
0101     n += scnprintf(&buf[n], PAGE_SIZE - n,
0102               "num_of_padd_cols = %d\n", p->num_of_padd_cols);
0103     n += scnprintf(&buf[n], PAGE_SIZE - n,
0104               "num_of_punct_cols = %d\n", p->num_of_punct_cols);
0105     n += scnprintf(&buf[n], PAGE_SIZE - n,
0106               "error_ts_packets = %d\n", p->error_ts_packets);
0107     n += scnprintf(&buf[n], PAGE_SIZE - n,
0108               "total_ts_packets = %d\n", p->total_ts_packets);
0109     n += scnprintf(&buf[n], PAGE_SIZE - n,
0110               "num_of_valid_mpe_tlbs = %d\n", p->num_of_valid_mpe_tlbs);
0111     n += scnprintf(&buf[n], PAGE_SIZE - n,
0112               "num_of_invalid_mpe_tlbs = %d\n", p->num_of_invalid_mpe_tlbs);
0113     n += scnprintf(&buf[n], PAGE_SIZE - n,
0114               "num_of_corrected_mpe_tlbs = %d\n", p->num_of_corrected_mpe_tlbs);
0115     n += scnprintf(&buf[n], PAGE_SIZE - n,
0116               "ber_error_count = %d\n", p->ber_error_count);
0117     n += scnprintf(&buf[n], PAGE_SIZE - n,
0118               "ber_bit_count = %d\n", p->ber_bit_count);
0119     n += scnprintf(&buf[n], PAGE_SIZE - n,
0120               "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
0121     n += scnprintf(&buf[n], PAGE_SIZE - n,
0122               "pre_ber = %d\n", p->pre_ber);
0123     n += scnprintf(&buf[n], PAGE_SIZE - n,
0124               "cell_id = %d\n", p->cell_id);
0125     n += scnprintf(&buf[n], PAGE_SIZE - n,
0126               "dvbh_srv_ind_hp = %d\n", p->dvbh_srv_ind_hp);
0127     n += scnprintf(&buf[n], PAGE_SIZE - n,
0128               "dvbh_srv_ind_lp = %d\n", p->dvbh_srv_ind_lp);
0129     n += scnprintf(&buf[n], PAGE_SIZE - n,
0130               "num_mpe_received = %d\n", p->num_mpe_received);
0131 
0132     debug_data->stats_count = n;
0133     spin_unlock(&debug_data->lock);
0134     wake_up(&debug_data->stats_queue);
0135 }
0136 
0137 static void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data,
0138                  struct sms_isdbt_stats *p)
0139 {
0140     int i, n = 0;
0141     char *buf;
0142 
0143     spin_lock(&debug_data->lock);
0144     if (debug_data->stats_count) {
0145         spin_unlock(&debug_data->lock);
0146         return;
0147     }
0148 
0149     buf = debug_data->stats_data;
0150 
0151     n += scnprintf(&buf[n], PAGE_SIZE - n,
0152               "statistics_type = %d\t", p->statistics_type);
0153     n += scnprintf(&buf[n], PAGE_SIZE - n,
0154               "full_size = %d\n", p->full_size);
0155 
0156     n += scnprintf(&buf[n], PAGE_SIZE - n,
0157               "is_rf_locked = %d\t\t", p->is_rf_locked);
0158     n += scnprintf(&buf[n], PAGE_SIZE - n,
0159               "is_demod_locked = %d\t", p->is_demod_locked);
0160     n += scnprintf(&buf[n], PAGE_SIZE - n,
0161               "is_external_lna_on = %d\n", p->is_external_lna_on);
0162     n += scnprintf(&buf[n], PAGE_SIZE - n,
0163               "SNR = %d dB\t\t", p->SNR);
0164     n += scnprintf(&buf[n], PAGE_SIZE - n,
0165               "RSSI = %d dBm\t\t", p->RSSI);
0166     n += scnprintf(&buf[n], PAGE_SIZE - n,
0167               "in_band_pwr = %d dBm\n", p->in_band_pwr);
0168     n += scnprintf(&buf[n], PAGE_SIZE - n,
0169               "carrier_offset = %d\t", p->carrier_offset);
0170     n += scnprintf(&buf[n], PAGE_SIZE - n,
0171               "bandwidth = %d\t\t", p->bandwidth);
0172     n += scnprintf(&buf[n], PAGE_SIZE - n,
0173               "frequency = %d Hz\n", p->frequency);
0174     n += scnprintf(&buf[n], PAGE_SIZE - n,
0175               "transmission_mode = %d\t", p->transmission_mode);
0176     n += scnprintf(&buf[n], PAGE_SIZE - n,
0177               "modem_state = %d\t\t", p->modem_state);
0178     n += scnprintf(&buf[n], PAGE_SIZE - n,
0179               "guard_interval = %d\n", p->guard_interval);
0180     n += scnprintf(&buf[n], PAGE_SIZE - n,
0181               "system_type = %d\t\t", p->system_type);
0182     n += scnprintf(&buf[n], PAGE_SIZE - n,
0183               "partial_reception = %d\t", p->partial_reception);
0184     n += scnprintf(&buf[n], PAGE_SIZE - n,
0185               "num_of_layers = %d\n", p->num_of_layers);
0186     n += scnprintf(&buf[n], PAGE_SIZE - n,
0187               "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
0188 
0189     for (i = 0; i < 3; i++) {
0190         if (p->layer_info[i].number_of_segments < 1 ||
0191             p->layer_info[i].number_of_segments > 13)
0192             continue;
0193 
0194         n += scnprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
0195         n += scnprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
0196                   p->layer_info[i].code_rate);
0197         n += scnprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
0198                   p->layer_info[i].constellation);
0199         n += scnprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
0200                   p->layer_info[i].ber);
0201         n += scnprintf(&buf[n], PAGE_SIZE - n,
0202                   "\tber_error_count = %-5d\t",
0203                   p->layer_info[i].ber_error_count);
0204         n += scnprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
0205                   p->layer_info[i].ber_bit_count);
0206         n += scnprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
0207                   p->layer_info[i].pre_ber);
0208         n += scnprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
0209                   p->layer_info[i].ts_per);
0210         n += scnprintf(&buf[n], PAGE_SIZE - n,
0211                   "\terror_ts_packets = %-5d\t",
0212                   p->layer_info[i].error_ts_packets);
0213         n += scnprintf(&buf[n], PAGE_SIZE - n,
0214                   "total_ts_packets = %-5d\t",
0215                   p->layer_info[i].total_ts_packets);
0216         n += scnprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
0217                   p->layer_info[i].ti_ldepth_i);
0218         n += scnprintf(&buf[n], PAGE_SIZE - n,
0219                   "\tnumber_of_segments = %d\t",
0220                   p->layer_info[i].number_of_segments);
0221         n += scnprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
0222                   p->layer_info[i].tmcc_errors);
0223     }
0224 
0225     debug_data->stats_count = n;
0226     spin_unlock(&debug_data->lock);
0227     wake_up(&debug_data->stats_queue);
0228 }
0229 
0230 static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data,
0231                 struct sms_isdbt_stats_ex *p)
0232 {
0233     int i, n = 0;
0234     char *buf;
0235 
0236     spin_lock(&debug_data->lock);
0237     if (debug_data->stats_count) {
0238         spin_unlock(&debug_data->lock);
0239         return;
0240     }
0241 
0242     buf = debug_data->stats_data;
0243 
0244     n += scnprintf(&buf[n], PAGE_SIZE - n,
0245               "statistics_type = %d\t", p->statistics_type);
0246     n += scnprintf(&buf[n], PAGE_SIZE - n,
0247               "full_size = %d\n", p->full_size);
0248 
0249     n += scnprintf(&buf[n], PAGE_SIZE - n,
0250               "is_rf_locked = %d\t\t", p->is_rf_locked);
0251     n += scnprintf(&buf[n], PAGE_SIZE - n,
0252               "is_demod_locked = %d\t", p->is_demod_locked);
0253     n += scnprintf(&buf[n], PAGE_SIZE - n,
0254               "is_external_lna_on = %d\n", p->is_external_lna_on);
0255     n += scnprintf(&buf[n], PAGE_SIZE - n,
0256               "SNR = %d dB\t\t", p->SNR);
0257     n += scnprintf(&buf[n], PAGE_SIZE - n,
0258               "RSSI = %d dBm\t\t", p->RSSI);
0259     n += scnprintf(&buf[n], PAGE_SIZE - n,
0260               "in_band_pwr = %d dBm\n", p->in_band_pwr);
0261     n += scnprintf(&buf[n], PAGE_SIZE - n,
0262               "carrier_offset = %d\t", p->carrier_offset);
0263     n += scnprintf(&buf[n], PAGE_SIZE - n,
0264               "bandwidth = %d\t\t", p->bandwidth);
0265     n += scnprintf(&buf[n], PAGE_SIZE - n,
0266               "frequency = %d Hz\n", p->frequency);
0267     n += scnprintf(&buf[n], PAGE_SIZE - n,
0268               "transmission_mode = %d\t", p->transmission_mode);
0269     n += scnprintf(&buf[n], PAGE_SIZE - n,
0270               "modem_state = %d\t\t", p->modem_state);
0271     n += scnprintf(&buf[n], PAGE_SIZE - n,
0272               "guard_interval = %d\n", p->guard_interval);
0273     n += scnprintf(&buf[n], PAGE_SIZE - n,
0274               "system_type = %d\t\t", p->system_type);
0275     n += scnprintf(&buf[n], PAGE_SIZE - n,
0276               "partial_reception = %d\t", p->partial_reception);
0277     n += scnprintf(&buf[n], PAGE_SIZE - n,
0278               "num_of_layers = %d\n", p->num_of_layers);
0279     n += scnprintf(&buf[n], PAGE_SIZE - n, "segment_number = %d\t",
0280               p->segment_number);
0281     n += scnprintf(&buf[n], PAGE_SIZE - n, "tune_bw = %d\n",
0282               p->tune_bw);
0283 
0284     for (i = 0; i < 3; i++) {
0285         if (p->layer_info[i].number_of_segments < 1 ||
0286             p->layer_info[i].number_of_segments > 13)
0287             continue;
0288 
0289         n += scnprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
0290         n += scnprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
0291                   p->layer_info[i].code_rate);
0292         n += scnprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
0293                   p->layer_info[i].constellation);
0294         n += scnprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
0295                   p->layer_info[i].ber);
0296         n += scnprintf(&buf[n], PAGE_SIZE - n,
0297                   "\tber_error_count = %-5d\t",
0298                   p->layer_info[i].ber_error_count);
0299         n += scnprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
0300                   p->layer_info[i].ber_bit_count);
0301         n += scnprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
0302                   p->layer_info[i].pre_ber);
0303         n += scnprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
0304                   p->layer_info[i].ts_per);
0305         n += scnprintf(&buf[n], PAGE_SIZE - n,
0306                   "\terror_ts_packets = %-5d\t",
0307                   p->layer_info[i].error_ts_packets);
0308         n += scnprintf(&buf[n], PAGE_SIZE - n,
0309                   "total_ts_packets = %-5d\t",
0310                   p->layer_info[i].total_ts_packets);
0311         n += scnprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
0312                   p->layer_info[i].ti_ldepth_i);
0313         n += scnprintf(&buf[n], PAGE_SIZE - n,
0314                   "\tnumber_of_segments = %d\t",
0315                   p->layer_info[i].number_of_segments);
0316         n += scnprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
0317                   p->layer_info[i].tmcc_errors);
0318     }
0319 
0320 
0321     debug_data->stats_count = n;
0322     spin_unlock(&debug_data->lock);
0323 
0324     wake_up(&debug_data->stats_queue);
0325 }
0326 
0327 static int smsdvb_stats_open(struct inode *inode, struct file *file)
0328 {
0329     struct smsdvb_client_t *client = inode->i_private;
0330     struct smsdvb_debugfs *debug_data = client->debug_data;
0331 
0332     kref_get(&debug_data->refcount);
0333 
0334     spin_lock(&debug_data->lock);
0335     debug_data->stats_count = 0;
0336     debug_data->stats_was_read = false;
0337     spin_unlock(&debug_data->lock);
0338 
0339     file->private_data = debug_data;
0340 
0341     return 0;
0342 }
0343 
0344 static void smsdvb_debugfs_data_release(struct kref *ref)
0345 {
0346     struct smsdvb_debugfs *debug_data;
0347 
0348     debug_data = container_of(ref, struct smsdvb_debugfs, refcount);
0349     kfree(debug_data);
0350 }
0351 
0352 static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data)
0353 {
0354     int rc = 1;
0355 
0356     spin_lock(&debug_data->lock);
0357 
0358     if (debug_data->stats_was_read)
0359         goto exit;
0360 
0361     rc = debug_data->stats_count;
0362 
0363 exit:
0364     spin_unlock(&debug_data->lock);
0365     return rc;
0366 }
0367 
0368 static __poll_t smsdvb_stats_poll(struct file *file, poll_table *wait)
0369 {
0370     struct smsdvb_debugfs *debug_data = file->private_data;
0371     int rc;
0372 
0373     kref_get(&debug_data->refcount);
0374 
0375     poll_wait(file, &debug_data->stats_queue, wait);
0376 
0377     rc = smsdvb_stats_wait_read(debug_data);
0378     kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
0379 
0380     return rc > 0 ? EPOLLIN | EPOLLRDNORM : 0;
0381 }
0382 
0383 static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
0384                       size_t nbytes, loff_t *ppos)
0385 {
0386     int rc = 0, len;
0387     struct smsdvb_debugfs *debug_data = file->private_data;
0388 
0389     kref_get(&debug_data->refcount);
0390 
0391     if (file->f_flags & O_NONBLOCK) {
0392         rc = smsdvb_stats_wait_read(debug_data);
0393         if (!rc) {
0394             rc = -EWOULDBLOCK;
0395             goto ret;
0396         }
0397     } else {
0398         rc = wait_event_interruptible(debug_data->stats_queue,
0399                       smsdvb_stats_wait_read(debug_data));
0400         if (rc < 0)
0401             goto ret;
0402     }
0403 
0404     if (debug_data->stats_was_read) {
0405         rc = 0; /* EOF */
0406         goto ret;
0407     }
0408 
0409     len = debug_data->stats_count - *ppos;
0410     if (len >= 0)
0411         rc = simple_read_from_buffer(user_buf, nbytes, ppos,
0412                          debug_data->stats_data, len);
0413     else
0414         rc = 0;
0415 
0416     if (*ppos >= debug_data->stats_count) {
0417         spin_lock(&debug_data->lock);
0418         debug_data->stats_was_read = true;
0419         spin_unlock(&debug_data->lock);
0420     }
0421 ret:
0422     kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
0423     return rc;
0424 }
0425 
0426 static int smsdvb_stats_release(struct inode *inode, struct file *file)
0427 {
0428     struct smsdvb_debugfs *debug_data = file->private_data;
0429 
0430     spin_lock(&debug_data->lock);
0431     debug_data->stats_was_read = true;  /* return EOF to read() */
0432     spin_unlock(&debug_data->lock);
0433     wake_up_interruptible_sync(&debug_data->stats_queue);
0434 
0435     kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
0436     file->private_data = NULL;
0437 
0438     return 0;
0439 }
0440 
0441 static const struct file_operations debugfs_stats_ops = {
0442     .open = smsdvb_stats_open,
0443     .poll = smsdvb_stats_poll,
0444     .read = smsdvb_stats_read,
0445     .release = smsdvb_stats_release,
0446     .llseek = generic_file_llseek,
0447 };
0448 
0449 /*
0450  * Functions used by smsdvb, in order to create the interfaces
0451  */
0452 
0453 int smsdvb_debugfs_create(struct smsdvb_client_t *client)
0454 {
0455     struct smscore_device_t *coredev = client->coredev;
0456     struct dentry *d;
0457     struct smsdvb_debugfs *debug_data;
0458 
0459     if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device)
0460         return -ENODEV;
0461 
0462     client->debugfs = debugfs_create_dir(coredev->devpath,
0463                          smsdvb_debugfs_usb_root);
0464     if (IS_ERR_OR_NULL(client->debugfs)) {
0465         pr_info("Unable to create debugfs %s directory.\n",
0466             coredev->devpath);
0467         return -ENODEV;
0468     }
0469 
0470     d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
0471                 client, &debugfs_stats_ops);
0472     if (!d) {
0473         debugfs_remove(client->debugfs);
0474         return -ENOMEM;
0475     }
0476 
0477     debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL);
0478     if (!debug_data)
0479         return -ENOMEM;
0480 
0481     client->debug_data        = debug_data;
0482     client->prt_dvb_stats     = smsdvb_print_dvb_stats;
0483     client->prt_isdb_stats    = smsdvb_print_isdb_stats;
0484     client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex;
0485 
0486     init_waitqueue_head(&debug_data->stats_queue);
0487     spin_lock_init(&debug_data->lock);
0488     kref_init(&debug_data->refcount);
0489 
0490     return 0;
0491 }
0492 
0493 void smsdvb_debugfs_release(struct smsdvb_client_t *client)
0494 {
0495     if (!client->debugfs)
0496         return;
0497 
0498     client->prt_dvb_stats     = NULL;
0499     client->prt_isdb_stats    = NULL;
0500     client->prt_isdb_stats_ex = NULL;
0501 
0502     debugfs_remove_recursive(client->debugfs);
0503     kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release);
0504 
0505     client->debug_data = NULL;
0506     client->debugfs = NULL;
0507 }
0508 
0509 void smsdvb_debugfs_register(void)
0510 {
0511     struct dentry *d;
0512 
0513     /*
0514      * FIXME: This was written to debug Siano USB devices. So, it creates
0515      * the debugfs node under <debugfs>/usb.
0516      * A similar logic would be needed for Siano sdio devices, but, in that
0517      * case, usb_debug_root is not a good choice.
0518      *
0519      * Perhaps the right fix here would be to create another sysfs root
0520      * node for sdio-based boards, but this may need some logic at sdio
0521      * subsystem.
0522      */
0523     d = debugfs_create_dir("smsdvb", usb_debug_root);
0524     if (IS_ERR_OR_NULL(d)) {
0525         pr_err("Couldn't create sysfs node for smsdvb\n");
0526         return;
0527     }
0528     smsdvb_debugfs_usb_root = d;
0529 }
0530 
0531 void smsdvb_debugfs_unregister(void)
0532 {
0533     if (!smsdvb_debugfs_usb_root)
0534         return;
0535     debugfs_remove_recursive(smsdvb_debugfs_usb_root);
0536     smsdvb_debugfs_usb_root = NULL;
0537 }