aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-03-10 08:04:44 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-21 06:48:41 -0400
commit503efe5cfc9fb9f67a6659c4ab39174b442876f3 (patch)
tree571f126b52f1d0ed78e009d1f00cf5f9c3b1c4a1 /drivers
parent3f6b87cff66bb8507aefd62559c516dd7c8f822a (diff)
[media] siano: split debugfs code into a separate file
To avoid mixing two different things at the same place, move the debugfs code into a separate file. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/common/siano/Kconfig12
-rw-r--r--drivers/media/common/siano/Makefile5
-rw-r--r--drivers/media/common/siano/smscoreapi.h6
-rw-r--r--drivers/media/common/siano/smsdvb-debugfs.c503
-rw-r--r--drivers/media/common/siano/smsdvb-main.c (renamed from drivers/media/common/siano/smsdvb.c)447
-rw-r--r--drivers/media/common/siano/smsdvb.h124
-rw-r--r--drivers/media/usb/siano/smsusb.c2
7 files changed, 666 insertions, 433 deletions
diff --git a/drivers/media/common/siano/Kconfig b/drivers/media/common/siano/Kconfig
index 68f0f604678e..f3f5ec44e685 100644
--- a/drivers/media/common/siano/Kconfig
+++ b/drivers/media/common/siano/Kconfig
@@ -17,3 +17,15 @@ config SMS_SIANO_RC
17 default y 17 default y
18 ---help--- 18 ---help---
19 Choose Y to select Remote Controller support for Siano driver. 19 Choose Y to select Remote Controller support for Siano driver.
20
21config SMS_SIANO_DEBUGFS
22 bool "Enable debugfs for smsdvb"
23 depends on SMS_SIANO_MDTV
24 depends on DEBUG_FS
25 depends on SMS_USB_DRV
26 ---help---
27 Choose Y to enable visualizing a dump of the frontend
28 statistics response packets via debugfs. Currently, works
29 only with Siano USB devices.
30
31 Useful only for developers. In doubt, say N.
diff --git a/drivers/media/common/siano/Makefile b/drivers/media/common/siano/Makefile
index 81b1e985bea5..4c0567f106b2 100644
--- a/drivers/media/common/siano/Makefile
+++ b/drivers/media/common/siano/Makefile
@@ -1,4 +1,5 @@
1smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o 1smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o
2smsdvb-objs := smsdvb-main.o
2 3
3obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o 4obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
4 5
@@ -6,6 +7,10 @@ ifeq ($(CONFIG_SMS_SIANO_RC),y)
6 smsmdtv-objs += smsir.o 7 smsmdtv-objs += smsir.o
7endif 8endif
8 9
10ifeq ($(CONFIG_SMS_SIANO_DEBUGFS),y)
11 smsdvb-objs += smsdvb-debugfs.o
12endif
13
9ccflags-y += -Idrivers/media/dvb-core 14ccflags-y += -Idrivers/media/dvb-core
10ccflags-y += $(extra-cflags-y) $(extra-cflags-m) 15ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
11 16
diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h
index 7925c04e3edc..53b81cbc1bda 100644
--- a/drivers/media/common/siano/smscoreapi.h
+++ b/drivers/media/common/siano/smscoreapi.h
@@ -184,6 +184,12 @@ struct smscore_device_t {
184 /* Infrared (IR) */ 184 /* Infrared (IR) */
185 struct ir_t ir; 185 struct ir_t ir;
186 186
187 /*
188 * Identify if device is USB or not.
189 * Used by smsdvb-sysfs to know the root node for debugfs
190 */
191 bool is_usb_device;
192
187 int led_state; 193 int led_state;
188}; 194};
189 195
diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c
new file mode 100644
index 000000000000..4d5dd471e2e1
--- /dev/null
+++ b/drivers/media/common/siano/smsdvb-debugfs.c
@@ -0,0 +1,503 @@
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
38static struct dentry *smsdvb_debugfs_usb_root;
39
40struct 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
51void 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 "IsRfLocked = %d\n", p->IsRfLocked);
67 n += snprintf(&buf[n], PAGE_SIZE - n,
68 "IsDemodLocked = %d\n", p->IsDemodLocked);
69 n += snprintf(&buf[n], PAGE_SIZE - n,
70 "IsExternalLNAOn = %d\n", p->IsExternalLNAOn);
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 "InBandPwr = %d\n", p->InBandPwr);
85 n += snprintf(&buf[n], PAGE_SIZE - n,
86 "CarrierOffset = %d\n", p->CarrierOffset);
87 n += snprintf(&buf[n], PAGE_SIZE - n,
88 "ModemState = %d\n", p->ModemState);
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 "TransmissionMode = %d\n", p->TransmissionMode);
95 n += snprintf(&buf[n], PAGE_SIZE - n,
96 "ModemState = %d\n", p->ModemState);
97 n += snprintf(&buf[n], PAGE_SIZE - n,
98 "GuardInterval = %d\n", p->GuardInterval);
99 n += snprintf(&buf[n], PAGE_SIZE - n,
100 "CodeRate = %d\n", p->CodeRate);
101 n += snprintf(&buf[n], PAGE_SIZE - n,
102 "LPCodeRate = %d\n", p->LPCodeRate);
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 "BurstSize = %d\n", p->BurstSize);
109 n += snprintf(&buf[n], PAGE_SIZE - n,
110 "BurstDuration = %d\n", p->BurstDuration);
111 n += snprintf(&buf[n], PAGE_SIZE - n,
112 "BurstCycleTime = %d\n", p->BurstCycleTime);
113 n += snprintf(&buf[n], PAGE_SIZE - n,
114 "CalculatedBurstCycleTime = %d\n",
115 p->CalculatedBurstCycleTime);
116 n += snprintf(&buf[n], PAGE_SIZE - n,
117 "NumOfRows = %d\n", p->NumOfRows);
118 n += snprintf(&buf[n], PAGE_SIZE - n,
119 "NumOfPaddCols = %d\n", p->NumOfPaddCols);
120 n += snprintf(&buf[n], PAGE_SIZE - n,
121 "NumOfPunctCols = %d\n", p->NumOfPunctCols);
122 n += snprintf(&buf[n], PAGE_SIZE - n,
123 "ErrorTSPackets = %d\n", p->ErrorTSPackets);
124 n += snprintf(&buf[n], PAGE_SIZE - n,
125 "TotalTSPackets = %d\n", p->TotalTSPackets);
126 n += snprintf(&buf[n], PAGE_SIZE - n,
127 "NumOfValidMpeTlbs = %d\n", p->NumOfValidMpeTlbs);
128 n += snprintf(&buf[n], PAGE_SIZE - n,
129 "NumOfInvalidMpeTlbs = %d\n", p->NumOfInvalidMpeTlbs);
130 n += snprintf(&buf[n], PAGE_SIZE - n,
131 "NumOfCorrectedMpeTlbs = %d\n", p->NumOfCorrectedMpeTlbs);
132 n += snprintf(&buf[n], PAGE_SIZE - n,
133 "BERErrorCount = %d\n", p->BERErrorCount);
134 n += snprintf(&buf[n], PAGE_SIZE - n,
135 "BERBitCount = %d\n", p->BERBitCount);
136 n += snprintf(&buf[n], PAGE_SIZE - n,
137 "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors);
138 n += snprintf(&buf[n], PAGE_SIZE - n,
139 "PreBER = %d\n", p->PreBER);
140 n += snprintf(&buf[n], PAGE_SIZE - n,
141 "CellId = %d\n", p->CellId);
142 n += snprintf(&buf[n], PAGE_SIZE - n,
143 "DvbhSrvIndHP = %d\n", p->DvbhSrvIndHP);
144 n += snprintf(&buf[n], PAGE_SIZE - n,
145 "DvbhSrvIndLP = %d\n", p->DvbhSrvIndLP);
146 n += snprintf(&buf[n], PAGE_SIZE - n,
147 "NumMPEReceived = %d\n", p->NumMPEReceived);
148
149 debug_data->stats_count = n;
150 spin_unlock(&debug_data->lock);
151 wake_up(&debug_data->stats_queue);
152}
153
154void 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 "IsRfLocked = %d\t\t", p->IsRfLocked);
170 n += snprintf(&buf[n], PAGE_SIZE - n,
171 "IsDemodLocked = %d\t", p->IsDemodLocked);
172 n += snprintf(&buf[n], PAGE_SIZE - n,
173 "IsExternalLNAOn = %d\n", p->IsExternalLNAOn);
174 n += snprintf(&buf[n], PAGE_SIZE - n,
175 "SNR = %d dB\t\t", p->SNR);
176 n += snprintf(&buf[n], PAGE_SIZE - n,
177 "RSSI = %d dBm\t\t", p->RSSI);
178 n += snprintf(&buf[n], PAGE_SIZE - n,
179 "InBandPwr = %d dBm\n", p->InBandPwr);
180 n += snprintf(&buf[n], PAGE_SIZE - n,
181 "CarrierOffset = %d\t", p->CarrierOffset);
182 n += snprintf(&buf[n], PAGE_SIZE - n,
183 "Bandwidth = %d\t\t", p->Bandwidth);
184 n += snprintf(&buf[n], PAGE_SIZE - n,
185 "Frequency = %d Hz\n", p->Frequency);
186 n += snprintf(&buf[n], PAGE_SIZE - n,
187 "TransmissionMode = %d\t", p->TransmissionMode);
188 n += snprintf(&buf[n], PAGE_SIZE - n,
189 "ModemState = %d\t\t", p->ModemState);
190 n += snprintf(&buf[n], PAGE_SIZE - n,
191 "GuardInterval = %d\n", p->GuardInterval);
192 n += snprintf(&buf[n], PAGE_SIZE - n,
193 "SystemType = %d\t\t", p->SystemType);
194 n += snprintf(&buf[n], PAGE_SIZE - n,
195 "PartialReception = %d\t", p->PartialReception);
196 n += snprintf(&buf[n], PAGE_SIZE - n,
197 "NumOfLayers = %d\n", p->NumOfLayers);
198 n += snprintf(&buf[n], PAGE_SIZE - n,
199 "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors);
200
201 for (i = 0; i < 3; i++) {
202 if (p->LayerInfo[i].NumberOfSegments < 1 ||
203 p->LayerInfo[i].NumberOfSegments > 13)
204 continue;
205
206 n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
207 n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t",
208 p->LayerInfo[i].CodeRate);
209 n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n",
210 p->LayerInfo[i].Constellation);
211 n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t",
212 p->LayerInfo[i].BER);
213 n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t",
214 p->LayerInfo[i].BERErrorCount);
215 n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n",
216 p->LayerInfo[i].BERBitCount);
217 n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t",
218 p->LayerInfo[i].PreBER);
219 n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n",
220 p->LayerInfo[i].TS_PER);
221 n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t",
222 p->LayerInfo[i].ErrorTSPackets);
223 n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t",
224 p->LayerInfo[i].TotalTSPackets);
225 n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n",
226 p->LayerInfo[i].TILdepthI);
227 n += snprintf(&buf[n], PAGE_SIZE - n,
228 "\tNumberOfSegments = %d\t",
229 p->LayerInfo[i].NumberOfSegments);
230 n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n",
231 p->LayerInfo[i].TMCCErrors);
232 }
233
234 debug_data->stats_count = n;
235 spin_unlock(&debug_data->lock);
236 wake_up(&debug_data->stats_queue);
237}
238
239void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data,
240 struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p)
241{
242 int i, n = 0;
243 char *buf;
244
245 spin_lock(&debug_data->lock);
246 if (debug_data->stats_count) {
247 spin_unlock(&debug_data->lock);
248 return;
249 }
250
251 buf = debug_data->stats_data;
252
253 n += snprintf(&buf[n], PAGE_SIZE - n,
254 "IsRfLocked = %d\t\t", p->IsRfLocked);
255 n += snprintf(&buf[n], PAGE_SIZE - n,
256 "IsDemodLocked = %d\t", p->IsDemodLocked);
257 n += snprintf(&buf[n], PAGE_SIZE - n,
258 "IsExternalLNAOn = %d\n", p->IsExternalLNAOn);
259 n += snprintf(&buf[n], PAGE_SIZE - n,
260 "SNR = %d dB\t\t", p->SNR);
261 n += snprintf(&buf[n], PAGE_SIZE - n,
262 "RSSI = %d dBm\t\t", p->RSSI);
263 n += snprintf(&buf[n], PAGE_SIZE - n,
264 "InBandPwr = %d dBm\n", p->InBandPwr);
265 n += snprintf(&buf[n], PAGE_SIZE - n,
266 "CarrierOffset = %d\t", p->CarrierOffset);
267 n += snprintf(&buf[n], PAGE_SIZE - n,
268 "Bandwidth = %d\t\t", p->Bandwidth);
269 n += snprintf(&buf[n], PAGE_SIZE - n,
270 "Frequency = %d Hz\n", p->Frequency);
271 n += snprintf(&buf[n], PAGE_SIZE - n,
272 "TransmissionMode = %d\t", p->TransmissionMode);
273 n += snprintf(&buf[n], PAGE_SIZE - n,
274 "ModemState = %d\t\t", p->ModemState);
275 n += snprintf(&buf[n], PAGE_SIZE - n,
276 "GuardInterval = %d\n", p->GuardInterval);
277 n += snprintf(&buf[n], PAGE_SIZE - n,
278 "SystemType = %d\t\t", p->SystemType);
279 n += snprintf(&buf[n], PAGE_SIZE - n,
280 "PartialReception = %d\t", p->PartialReception);
281 n += snprintf(&buf[n], PAGE_SIZE - n,
282 "NumOfLayers = %d\n", p->NumOfLayers);
283 n += snprintf(&buf[n], PAGE_SIZE - n, "SegmentNumber = %d\t",
284 p->SegmentNumber);
285 n += snprintf(&buf[n], PAGE_SIZE - n, "TuneBW = %d\n",
286 p->TuneBW);
287
288 for (i = 0; i < 3; i++) {
289 if (p->LayerInfo[i].NumberOfSegments < 1 ||
290 p->LayerInfo[i].NumberOfSegments > 13)
291 continue;
292
293 n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
294 n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t",
295 p->LayerInfo[i].CodeRate);
296 n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n",
297 p->LayerInfo[i].Constellation);
298 n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t",
299 p->LayerInfo[i].BER);
300 n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t",
301 p->LayerInfo[i].BERErrorCount);
302 n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n",
303 p->LayerInfo[i].BERBitCount);
304 n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t",
305 p->LayerInfo[i].PreBER);
306 n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n",
307 p->LayerInfo[i].TS_PER);
308 n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t",
309 p->LayerInfo[i].ErrorTSPackets);
310 n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t",
311 p->LayerInfo[i].TotalTSPackets);
312 n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n",
313 p->LayerInfo[i].TILdepthI);
314 n += snprintf(&buf[n], PAGE_SIZE - n,
315 "\tNumberOfSegments = %d\t",
316 p->LayerInfo[i].NumberOfSegments);
317 n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n",
318 p->LayerInfo[i].TMCCErrors);
319 }
320
321
322 debug_data->stats_count = n;
323 spin_unlock(&debug_data->lock);
324
325 wake_up(&debug_data->stats_queue);
326}
327
328static int smsdvb_stats_open(struct inode *inode, struct file *file)
329{
330 struct smsdvb_client_t *client = inode->i_private;
331 struct smsdvb_debugfs *debug_data = client->debug_data;
332
333 kref_get(&debug_data->refcount);
334
335 spin_lock(&debug_data->lock);
336 debug_data->stats_count = 0;
337 debug_data->stats_was_read = false;
338 spin_unlock(&debug_data->lock);
339
340 file->private_data = debug_data;
341
342 return 0;
343}
344
345static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data)
346{
347 int rc = 1;
348
349 spin_lock(&debug_data->lock);
350
351 if (debug_data->stats_was_read)
352 goto exit;
353
354 rc = debug_data->stats_count;
355
356exit:
357 spin_unlock(&debug_data->lock);
358 return rc;
359}
360
361static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
362 size_t nbytes, loff_t *ppos)
363{
364 int rc = 0;
365 struct smsdvb_debugfs *debug_data = file->private_data;
366
367 rc = wait_event_interruptible(debug_data->stats_queue,
368 smsdvb_stats_wait_read(debug_data));
369 if (rc < 0)
370 return rc;
371
372 rc = simple_read_from_buffer(user_buf, nbytes, ppos,
373 debug_data->stats_data,
374 debug_data->stats_count);
375 spin_lock(&debug_data->lock);
376 debug_data->stats_was_read = true;
377 spin_unlock(&debug_data->lock);
378
379 return rc;
380}
381
382static void smsdvb_debugfs_data_release(struct kref *ref)
383{
384 struct smsdvb_debugfs *debug_data;
385
386 debug_data = container_of(ref, struct smsdvb_debugfs, refcount);
387 kfree(debug_data);
388}
389
390static int smsdvb_stats_release(struct inode *inode, struct file *file)
391{
392 struct smsdvb_debugfs *debug_data = file->private_data;
393
394 spin_lock(&debug_data->lock);
395 debug_data->stats_was_read = true;
396 spin_unlock(&debug_data->lock);
397 wake_up_interruptible_sync(&debug_data->stats_queue);
398
399 kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
400 file->private_data = NULL;
401
402 return 0;
403}
404
405static const struct file_operations debugfs_stats_ops = {
406 .open = smsdvb_stats_open,
407 .read = smsdvb_stats_read,
408 .release = smsdvb_stats_release,
409 .llseek = generic_file_llseek,
410};
411
412/*
413 * Functions used by smsdvb, in order to create the interfaces
414 */
415
416int smsdvb_debugfs_create(struct smsdvb_client_t *client)
417{
418 struct smscore_device_t *coredev = client->coredev;
419 struct dentry *d;
420 struct smsdvb_debugfs *debug_data;
421
422 if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device)
423 return -ENODEV;
424
425 client->debugfs = debugfs_create_dir(coredev->devpath,
426 smsdvb_debugfs_usb_root);
427 if (IS_ERR_OR_NULL(client->debugfs)) {
428 pr_info("Unable to create debugfs %s directory.\n",
429 coredev->devpath);
430 return -ENODEV;
431 }
432
433 d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
434 client, &debugfs_stats_ops);
435 if (!d) {
436 debugfs_remove(client->debugfs);
437 return -ENOMEM;
438 }
439
440 debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL);
441 if (!debug_data)
442 return -ENOMEM;
443
444 client->debug_data = debug_data;
445 client->prt_dvb_stats = smsdvb_print_dvb_stats;
446 client->prt_isdb_stats = smsdvb_print_isdb_stats;
447 client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex;
448
449 init_waitqueue_head(&debug_data->stats_queue);
450 spin_lock_init(&debug_data->lock);
451 kref_init(&debug_data->refcount);
452
453 return 0;
454}
455
456void smsdvb_debugfs_release(struct smsdvb_client_t *client)
457{
458 if (!client->debugfs)
459 return;
460
461printk("%s\n", __func__);
462
463 client->prt_dvb_stats = NULL;
464 client->prt_isdb_stats = NULL;
465 client->prt_isdb_stats_ex = NULL;
466
467 debugfs_remove_recursive(client->debugfs);
468 kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release);
469
470 client->debug_data = NULL;
471 client->debugfs = NULL;
472}
473
474int smsdvb_debugfs_register(void)
475{
476 struct dentry *d;
477
478 /*
479 * FIXME: This was written to debug Siano USB devices. So, it creates
480 * the debugfs node under <debugfs>/usb.
481 * A similar logic would be needed for Siano sdio devices, but, in that
482 * case, usb_debug_root is not a good choice.
483 *
484 * Perhaps the right fix here would be to create another sysfs root
485 * node for sdio-based boards, but this may need some logic at sdio
486 * subsystem.
487 */
488 d = debugfs_create_dir("smsdvb", usb_debug_root);
489 if (IS_ERR_OR_NULL(d)) {
490 sms_err("Couldn't create sysfs node for smsdvb");
491 return PTR_ERR(d);
492 } else {
493 smsdvb_debugfs_usb_root = d;
494 }
495 return 0;
496}
497
498void smsdvb_debugfs_unregister(void)
499{
500 if (smsdvb_debugfs_usb_root)
501 debugfs_remove_recursive(smsdvb_debugfs_usb_root);
502 smsdvb_debugfs_usb_root = NULL;
503}
diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb-main.c
index aeadd8a42775..c14f10d5d6c0 100644
--- a/drivers/media/common/siano/smsdvb.c
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -22,7 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/debugfs.h>
26 25
27#include "dmxdev.h" 26#include "dmxdev.h"
28#include "dvbdev.h" 27#include "dvbdev.h"
@@ -32,38 +31,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
32#include "smscoreapi.h" 31#include "smscoreapi.h"
33#include "sms-cards.h" 32#include "sms-cards.h"
34 33
35DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 34#include "smsdvb.h"
36
37struct smsdvb_client_t {
38 struct list_head entry;
39
40 struct smscore_device_t *coredev;
41 struct smscore_client_t *smsclient;
42
43 struct dvb_adapter adapter;
44 struct dvb_demux demux;
45 struct dmxdev dmxdev;
46 struct dvb_frontend frontend;
47
48 fe_status_t fe_status;
49 35
50 struct completion tune_done; 36DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
51 struct completion stats_done;
52
53 int last_per;
54
55 int legacy_ber, legacy_per;
56
57 int event_fe_state;
58 int event_unc_state;
59
60 /* Stats debugfs data */
61 struct dentry *debugfs;
62 char *stats_data;
63 atomic_t stats_count;
64 bool stats_was_read;
65 wait_queue_head_t stats_queue;
66};
67 37
68static struct list_head g_smsdvb_clients; 38static struct list_head g_smsdvb_clients;
69static struct mutex g_smsdvb_clientslock; 39static struct mutex g_smsdvb_clientslock;
@@ -72,39 +42,6 @@ static int sms_dbg;
72module_param_named(debug, sms_dbg, int, 0644); 42module_param_named(debug, sms_dbg, int, 0644);
73MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); 43MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
74 44
75/*
76 * This struct is a mix of RECEPTION_STATISTICS_EX_S and SRVM_SIGNAL_STATUS_S.
77 * It was obtained by comparing the way it was filled by the original code
78 */
79struct RECEPTION_STATISTICS_PER_SLICES_S {
80 u32 result;
81 u32 snr;
82 s32 inBandPower;
83 u32 tsPackets;
84 u32 etsPackets;
85 u32 constellation;
86 u32 hpCode;
87 u32 tpsSrvIndLP;
88 u32 tpsSrvIndHP;
89 u32 cellId;
90 u32 reason;
91 u32 requestId;
92 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
93
94 u32 BER; /* Post Viterbi BER [1E-5] */
95 s32 RSSI; /* dBm */
96 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
97
98 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
99 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
100
101 u32 BERBitCount; /* Total number of SYNC bits. */
102 u32 BERErrorCount; /* Number of erronous SYNC bits. */
103
104 s32 MRC_SNR; /* dB */
105 s32 MRC_InBandPwr; /* In band power in dBM */
106 s32 MRC_RSSI; /* dBm */
107};
108 45
109u32 sms_to_bw_table[] = { 46u32 sms_to_bw_table[] = {
110 [BW_8_MHZ] = 8000000, 47 [BW_8_MHZ] = 8000000,
@@ -148,359 +85,6 @@ u32 sms_to_modulation_table[] = {
148 [3] = DQPSK, 85 [3] = DQPSK,
149}; 86};
150 87
151static struct dentry *smsdvb_debugfs;
152
153static void smsdvb_print_dvb_stats(struct smsdvb_client_t *client,
154 struct SMSHOSTLIB_STATISTICS_ST *p)
155{
156 int n = 0;
157 char *buf;
158
159 if (!client->stats_data || atomic_read(&client->stats_count))
160 return;
161
162 buf = client->stats_data;
163
164 n += snprintf(&buf[n], PAGE_SIZE - n,
165 "IsRfLocked = %d\n", p->IsRfLocked);
166 n += snprintf(&buf[n], PAGE_SIZE - n,
167 "IsDemodLocked = %d\n", p->IsDemodLocked);
168 n += snprintf(&buf[n], PAGE_SIZE - n,
169 "IsExternalLNAOn = %d\n", p->IsExternalLNAOn);
170 n += snprintf(&buf[n], PAGE_SIZE - n,
171 "SNR = %d\n", p->SNR);
172 n += snprintf(&buf[n], PAGE_SIZE - n,
173 "BER = %d\n", p->BER);
174 n += snprintf(&buf[n], PAGE_SIZE - n,
175 "FIB_CRC = %d\n", p->FIB_CRC);
176 n += snprintf(&buf[n], PAGE_SIZE - n,
177 "TS_PER = %d\n", p->TS_PER);
178 n += snprintf(&buf[n], PAGE_SIZE - n,
179 "MFER = %d\n", p->MFER);
180 n += snprintf(&buf[n], PAGE_SIZE - n,
181 "RSSI = %d\n", p->RSSI);
182 n += snprintf(&buf[n], PAGE_SIZE - n,
183 "InBandPwr = %d\n", p->InBandPwr);
184 n += snprintf(&buf[n], PAGE_SIZE - n,
185 "CarrierOffset = %d\n", p->CarrierOffset);
186 n += snprintf(&buf[n], PAGE_SIZE - n,
187 "ModemState = %d\n", p->ModemState);
188 n += snprintf(&buf[n], PAGE_SIZE - n,
189 "Frequency = %d\n", p->Frequency);
190 n += snprintf(&buf[n], PAGE_SIZE - n,
191 "Bandwidth = %d\n", p->Bandwidth);
192 n += snprintf(&buf[n], PAGE_SIZE - n,
193 "TransmissionMode = %d\n", p->TransmissionMode);
194 n += snprintf(&buf[n], PAGE_SIZE - n,
195 "ModemState = %d\n", p->ModemState);
196 n += snprintf(&buf[n], PAGE_SIZE - n,
197 "GuardInterval = %d\n", p->GuardInterval);
198 n += snprintf(&buf[n], PAGE_SIZE - n,
199 "CodeRate = %d\n", p->CodeRate);
200 n += snprintf(&buf[n], PAGE_SIZE - n,
201 "LPCodeRate = %d\n", p->LPCodeRate);
202 n += snprintf(&buf[n], PAGE_SIZE - n,
203 "Hierarchy = %d\n", p->Hierarchy);
204 n += snprintf(&buf[n], PAGE_SIZE - n,
205 "Constellation = %d\n", p->Constellation);
206 n += snprintf(&buf[n], PAGE_SIZE - n,
207 "BurstSize = %d\n", p->BurstSize);
208 n += snprintf(&buf[n], PAGE_SIZE - n,
209 "BurstDuration = %d\n", p->BurstDuration);
210 n += snprintf(&buf[n], PAGE_SIZE - n,
211 "BurstCycleTime = %d\n", p->BurstCycleTime);
212 n += snprintf(&buf[n], PAGE_SIZE - n,
213 "CalculatedBurstCycleTime = %d\n",
214 p->CalculatedBurstCycleTime);
215 n += snprintf(&buf[n], PAGE_SIZE - n,
216 "NumOfRows = %d\n", p->NumOfRows);
217 n += snprintf(&buf[n], PAGE_SIZE - n,
218 "NumOfPaddCols = %d\n", p->NumOfPaddCols);
219 n += snprintf(&buf[n], PAGE_SIZE - n,
220 "NumOfPunctCols = %d\n", p->NumOfPunctCols);
221 n += snprintf(&buf[n], PAGE_SIZE - n,
222 "ErrorTSPackets = %d\n", p->ErrorTSPackets);
223 n += snprintf(&buf[n], PAGE_SIZE - n,
224 "TotalTSPackets = %d\n", p->TotalTSPackets);
225 n += snprintf(&buf[n], PAGE_SIZE - n,
226 "NumOfValidMpeTlbs = %d\n", p->NumOfValidMpeTlbs);
227 n += snprintf(&buf[n], PAGE_SIZE - n,
228 "NumOfInvalidMpeTlbs = %d\n", p->NumOfInvalidMpeTlbs);
229 n += snprintf(&buf[n], PAGE_SIZE - n,
230 "NumOfCorrectedMpeTlbs = %d\n", p->NumOfCorrectedMpeTlbs);
231 n += snprintf(&buf[n], PAGE_SIZE - n,
232 "BERErrorCount = %d\n", p->BERErrorCount);
233 n += snprintf(&buf[n], PAGE_SIZE - n,
234 "BERBitCount = %d\n", p->BERBitCount);
235 n += snprintf(&buf[n], PAGE_SIZE - n,
236 "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors);
237 n += snprintf(&buf[n], PAGE_SIZE - n,
238 "PreBER = %d\n", p->PreBER);
239 n += snprintf(&buf[n], PAGE_SIZE - n,
240 "CellId = %d\n", p->CellId);
241 n += snprintf(&buf[n], PAGE_SIZE - n,
242 "DvbhSrvIndHP = %d\n", p->DvbhSrvIndHP);
243 n += snprintf(&buf[n], PAGE_SIZE - n,
244 "DvbhSrvIndLP = %d\n", p->DvbhSrvIndLP);
245 n += snprintf(&buf[n], PAGE_SIZE - n,
246 "NumMPEReceived = %d\n", p->NumMPEReceived);
247
248 atomic_set(&client->stats_count, n);
249 wake_up(&client->stats_queue);
250}
251
252static void smsdvb_print_isdb_stats(struct smsdvb_client_t *client,
253 struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
254{
255 int i, n = 0;
256 char *buf;
257
258 if (!client->stats_data || atomic_read(&client->stats_count))
259 return;
260
261 buf = client->stats_data;
262
263 n += snprintf(&buf[n], PAGE_SIZE - n,
264 "IsRfLocked = %d\t\t", p->IsRfLocked);
265 n += snprintf(&buf[n], PAGE_SIZE - n,
266 "IsDemodLocked = %d\t", p->IsDemodLocked);
267 n += snprintf(&buf[n], PAGE_SIZE - n,
268 "IsExternalLNAOn = %d\n", p->IsExternalLNAOn);
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 "InBandPwr = %d dBm\n", p->InBandPwr);
275 n += snprintf(&buf[n], PAGE_SIZE - n,
276 "CarrierOffset = %d\t", p->CarrierOffset);
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 "TransmissionMode = %d\t", p->TransmissionMode);
283 n += snprintf(&buf[n], PAGE_SIZE - n,
284 "ModemState = %d\t\t", p->ModemState);
285 n += snprintf(&buf[n], PAGE_SIZE - n,
286 "GuardInterval = %d\n", p->GuardInterval);
287 n += snprintf(&buf[n], PAGE_SIZE - n,
288 "SystemType = %d\t\t", p->SystemType);
289 n += snprintf(&buf[n], PAGE_SIZE - n,
290 "PartialReception = %d\t", p->PartialReception);
291 n += snprintf(&buf[n], PAGE_SIZE - n,
292 "NumOfLayers = %d\n", p->NumOfLayers);
293 n += snprintf(&buf[n], PAGE_SIZE - n,
294 "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors);
295
296 for (i = 0; i < 3; i++) {
297 if (p->LayerInfo[i].NumberOfSegments < 1 ||
298 p->LayerInfo[i].NumberOfSegments > 13)
299 continue;
300
301 n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
302 n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t",
303 p->LayerInfo[i].CodeRate);
304 n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n",
305 p->LayerInfo[i].Constellation);
306 n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t",
307 p->LayerInfo[i].BER);
308 n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t",
309 p->LayerInfo[i].BERErrorCount);
310 n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n",
311 p->LayerInfo[i].BERBitCount);
312 n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t",
313 p->LayerInfo[i].PreBER);
314 n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n",
315 p->LayerInfo[i].TS_PER);
316 n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t",
317 p->LayerInfo[i].ErrorTSPackets);
318 n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t",
319 p->LayerInfo[i].TotalTSPackets);
320 n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n",
321 p->LayerInfo[i].TILdepthI);
322 n += snprintf(&buf[n], PAGE_SIZE - n,
323 "\tNumberOfSegments = %d\t",
324 p->LayerInfo[i].NumberOfSegments);
325 n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n",
326 p->LayerInfo[i].TMCCErrors);
327 }
328
329 atomic_set(&client->stats_count, n);
330 wake_up(&client->stats_queue);
331}
332
333static void
334smsdvb_print_isdb_stats_ex(struct smsdvb_client_t *client,
335 struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p)
336{
337 int i, n = 0;
338 char *buf;
339
340 if (!client->stats_data || atomic_read(&client->stats_count))
341 return;
342
343 buf = client->stats_data;
344
345 n += snprintf(&buf[n], PAGE_SIZE - n,
346 "IsRfLocked = %d\t\t", p->IsRfLocked);
347 n += snprintf(&buf[n], PAGE_SIZE - n,
348 "IsDemodLocked = %d\t", p->IsDemodLocked);
349 n += snprintf(&buf[n], PAGE_SIZE - n,
350 "IsExternalLNAOn = %d\n", p->IsExternalLNAOn);
351 n += snprintf(&buf[n], PAGE_SIZE - n,
352 "SNR = %d dB\t\t", p->SNR);
353 n += snprintf(&buf[n], PAGE_SIZE - n,
354 "RSSI = %d dBm\t\t", p->RSSI);
355 n += snprintf(&buf[n], PAGE_SIZE - n,
356 "InBandPwr = %d dBm\n", p->InBandPwr);
357 n += snprintf(&buf[n], PAGE_SIZE - n,
358 "CarrierOffset = %d\t", p->CarrierOffset);
359 n += snprintf(&buf[n], PAGE_SIZE - n,
360 "Bandwidth = %d\t\t", p->Bandwidth);
361 n += snprintf(&buf[n], PAGE_SIZE - n,
362 "Frequency = %d Hz\n", p->Frequency);
363 n += snprintf(&buf[n], PAGE_SIZE - n,
364 "TransmissionMode = %d\t", p->TransmissionMode);
365 n += snprintf(&buf[n], PAGE_SIZE - n,
366 "ModemState = %d\t\t", p->ModemState);
367 n += snprintf(&buf[n], PAGE_SIZE - n,
368 "GuardInterval = %d\n", p->GuardInterval);
369 n += snprintf(&buf[n], PAGE_SIZE - n,
370 "SystemType = %d\t\t", p->SystemType);
371 n += snprintf(&buf[n], PAGE_SIZE - n,
372 "PartialReception = %d\t", p->PartialReception);
373 n += snprintf(&buf[n], PAGE_SIZE - n,
374 "NumOfLayers = %d\n", p->NumOfLayers);
375 n += snprintf(&buf[n], PAGE_SIZE - n, "SegmentNumber = %d\t",
376 p->SegmentNumber);
377 n += snprintf(&buf[n], PAGE_SIZE - n, "TuneBW = %d\n",
378 p->TuneBW);
379
380 for (i = 0; i < 3; i++) {
381 if (p->LayerInfo[i].NumberOfSegments < 1 ||
382 p->LayerInfo[i].NumberOfSegments > 13)
383 continue;
384
385 n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
386 n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t",
387 p->LayerInfo[i].CodeRate);
388 n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n",
389 p->LayerInfo[i].Constellation);
390 n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t",
391 p->LayerInfo[i].BER);
392 n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t",
393 p->LayerInfo[i].BERErrorCount);
394 n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n",
395 p->LayerInfo[i].BERBitCount);
396 n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t",
397 p->LayerInfo[i].PreBER);
398 n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n",
399 p->LayerInfo[i].TS_PER);
400 n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t",
401 p->LayerInfo[i].ErrorTSPackets);
402 n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t",
403 p->LayerInfo[i].TotalTSPackets);
404 n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n",
405 p->LayerInfo[i].TILdepthI);
406 n += snprintf(&buf[n], PAGE_SIZE - n,
407 "\tNumberOfSegments = %d\t",
408 p->LayerInfo[i].NumberOfSegments);
409 n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n",
410 p->LayerInfo[i].TMCCErrors);
411 }
412
413 atomic_set(&client->stats_count, n);
414 wake_up(&client->stats_queue);
415}
416
417static int smsdvb_stats_open(struct inode *inode, struct file *file)
418{
419 struct smsdvb_client_t *client = inode->i_private;
420
421 atomic_set(&client->stats_count, 0);
422 client->stats_was_read = false;
423
424 init_waitqueue_head(&client->stats_queue);
425
426 client->stats_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
427 if (client->stats_data == NULL)
428 return -ENOMEM;
429
430 file->private_data = client;
431
432 return 0;
433}
434
435static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
436 size_t nbytes, loff_t *ppos)
437{
438 struct smsdvb_client_t *client = file->private_data;
439
440 if (!client->stats_data || client->stats_was_read)
441 return 0;
442
443 wait_event_interruptible(client->stats_queue,
444 atomic_read(&client->stats_count));
445
446 return simple_read_from_buffer(user_buf, nbytes, ppos,
447 client->stats_data,
448 atomic_read(&client->stats_count));
449
450 client->stats_was_read = true;
451}
452
453static int smsdvb_stats_release(struct inode *inode, struct file *file)
454{
455 struct smsdvb_client_t *client = file->private_data;
456
457 kfree(client->stats_data);
458 client->stats_data = NULL;
459
460 return 0;
461}
462
463static const struct file_operations debugfs_stats_ops = {
464 .open = smsdvb_stats_open,
465 .read = smsdvb_stats_read,
466 .release = smsdvb_stats_release,
467 .llseek = generic_file_llseek,
468};
469
470static int create_stats_debugfs(struct smsdvb_client_t *client)
471{
472 struct smscore_device_t *coredev = client->coredev;
473 struct dentry *d;
474
475 if (!smsdvb_debugfs)
476 return -ENODEV;
477
478 client->debugfs = debugfs_create_dir(coredev->devpath, smsdvb_debugfs);
479 if (IS_ERR_OR_NULL(client->debugfs)) {
480 sms_info("Unable to create debugfs %s directory.\n",
481 coredev->devpath);
482 return -ENODEV;
483 }
484
485 d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
486 client, &debugfs_stats_ops);
487 if (!d) {
488 debugfs_remove(client->debugfs);
489 return -ENOMEM;
490 }
491
492 return 0;
493}
494
495static void release_stats_debugfs(struct smsdvb_client_t *client)
496{
497 if (!client->debugfs)
498 return;
499
500 debugfs_remove_recursive(client->debugfs);
501
502 client->debugfs = NULL;
503}
504 88
505/* Events that may come from DVB v3 adapter */ 89/* Events that may come from DVB v3 adapter */
506static void sms_board_dvb3_event(struct smsdvb_client_t *client, 90static void sms_board_dvb3_event(struct smsdvb_client_t *client,
@@ -708,7 +292,8 @@ static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client,
708 struct dvb_frontend *fe = &client->frontend; 292 struct dvb_frontend *fe = &client->frontend;
709 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 293 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
710 294
711 smsdvb_print_dvb_stats(client, p); 295 if (client->prt_dvb_stats)
296 client->prt_dvb_stats(client->debug_data, p);
712 297
713 client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); 298 client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked);
714 299
@@ -758,7 +343,8 @@ static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client,
758 struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; 343 struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr;
759 int i, n_layers; 344 int i, n_layers;
760 345
761 smsdvb_print_isdb_stats(client, p); 346 if (client->prt_isdb_stats)
347 client->prt_isdb_stats(client->debug_data, p);
762 348
763 /* Update ISDB-T transmission parameters */ 349 /* Update ISDB-T transmission parameters */
764 c->frequency = p->Frequency; 350 c->frequency = p->Frequency;
@@ -834,7 +420,8 @@ static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client,
834 struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; 420 struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr;
835 int i, n_layers; 421 int i, n_layers;
836 422
837 smsdvb_print_isdb_stats_ex(client, p); 423 if (client->prt_isdb_stats_ex)
424 client->prt_isdb_stats_ex(client->debug_data, p);
838 425
839 /* Update ISDB-T transmission parameters */ 426 /* Update ISDB-T transmission parameters */
840 c->frequency = p->Frequency; 427 c->frequency = p->Frequency;
@@ -998,7 +585,7 @@ static void smsdvb_unregister_client(struct smsdvb_client_t *client)
998 585
999 list_del(&client->entry); 586 list_del(&client->entry);
1000 587
1001 release_stats_debugfs(client); 588 smsdvb_debugfs_release(client);
1002 smscore_unregister_client(client->smsclient); 589 smscore_unregister_client(client->smsclient);
1003 dvb_unregister_frontend(&client->frontend); 590 dvb_unregister_frontend(&client->frontend);
1004 dvb_dmxdev_release(&client->dmxdev); 591 dvb_dmxdev_release(&client->dmxdev);
@@ -1288,6 +875,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
1288 struct sms_board *board = sms_get_board(board_id); 875 struct sms_board *board = sms_get_board(board_id);
1289 enum sms_device_type_st type = board->type; 876 enum sms_device_type_st type = board->type;
1290 int ret; 877 int ret;
878
1291 struct { 879 struct {
1292 struct SmsMsgHdr_ST Msg; 880 struct SmsMsgHdr_ST Msg;
1293 u32 Data[4]; 881 u32 Data[4];
@@ -1536,7 +1124,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
1536 sms_info("success"); 1124 sms_info("success");
1537 sms_board_setup(coredev); 1125 sms_board_setup(coredev);
1538 1126
1539 if (create_stats_debugfs(client) < 0) 1127 if (smsdvb_debugfs_create(client) < 0)
1540 sms_info("failed to create debugfs node"); 1128 sms_info("failed to create debugfs node");
1541 1129
1542 return 0; 1130 return 0;
@@ -1561,16 +1149,11 @@ adapter_error:
1561static int __init smsdvb_module_init(void) 1149static int __init smsdvb_module_init(void)
1562{ 1150{
1563 int rc; 1151 int rc;
1564 struct dentry *d;
1565 1152
1566 INIT_LIST_HEAD(&g_smsdvb_clients); 1153 INIT_LIST_HEAD(&g_smsdvb_clients);
1567 kmutex_init(&g_smsdvb_clientslock); 1154 kmutex_init(&g_smsdvb_clientslock);
1568 1155
1569 d = debugfs_create_dir("smsdvb", usb_debug_root); 1156 smsdvb_debugfs_register();
1570 if (IS_ERR_OR_NULL(d))
1571 sms_err("Couldn't create sysfs node for smsdvb");
1572 else
1573 smsdvb_debugfs = d;
1574 1157
1575 rc = smscore_register_hotplug(smsdvb_hotplug); 1158 rc = smscore_register_hotplug(smsdvb_hotplug);
1576 1159
@@ -1586,11 +1169,9 @@ static void __exit smsdvb_module_exit(void)
1586 kmutex_lock(&g_smsdvb_clientslock); 1169 kmutex_lock(&g_smsdvb_clientslock);
1587 1170
1588 while (!list_empty(&g_smsdvb_clients)) 1171 while (!list_empty(&g_smsdvb_clients))
1589 smsdvb_unregister_client( 1172 smsdvb_unregister_client((struct smsdvb_client_t *)g_smsdvb_clients.next);
1590 (struct smsdvb_client_t *) g_smsdvb_clients.next);
1591 1173
1592 if (smsdvb_debugfs) 1174 smsdvb_debugfs_unregister();
1593 debugfs_remove_recursive(smsdvb_debugfs);
1594 1175
1595 kmutex_unlock(&g_smsdvb_clientslock); 1176 kmutex_unlock(&g_smsdvb_clientslock);
1596} 1177}
diff --git a/drivers/media/common/siano/smsdvb.h b/drivers/media/common/siano/smsdvb.h
new file mode 100644
index 000000000000..09982bcf2535
--- /dev/null
+++ b/drivers/media/common/siano/smsdvb.h
@@ -0,0 +1,124 @@
1/***********************************************************************
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 ***********************************************************************/
17
18struct smsdvb_debugfs;
19struct smsdvb_client_t;
20
21typedef void (*sms_prt_dvb_stats_t)(struct smsdvb_debugfs *debug_data,
22 struct SMSHOSTLIB_STATISTICS_ST *p);
23
24typedef void (*sms_prt_isdb_stats_t)(struct smsdvb_debugfs *debug_data,
25 struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p);
26
27typedef void (*sms_prt_isdb_stats_ex_t)
28 (struct smsdvb_debugfs *debug_data,
29 struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p);
30
31
32struct smsdvb_client_t {
33 struct list_head entry;
34
35 struct smscore_device_t *coredev;
36 struct smscore_client_t *smsclient;
37
38 struct dvb_adapter adapter;
39 struct dvb_demux demux;
40 struct dmxdev dmxdev;
41 struct dvb_frontend frontend;
42
43 fe_status_t fe_status;
44
45 struct completion tune_done;
46 struct completion stats_done;
47
48 int last_per;
49
50 int legacy_ber, legacy_per;
51
52 int event_fe_state;
53 int event_unc_state;
54
55 /* Stats debugfs data */
56 struct dentry *debugfs;
57
58 struct smsdvb_debugfs *debug_data;
59
60 sms_prt_dvb_stats_t prt_dvb_stats;
61 sms_prt_isdb_stats_t prt_isdb_stats;
62 sms_prt_isdb_stats_ex_t prt_isdb_stats_ex;
63};
64
65/*
66 * This struct is a mix of RECEPTION_STATISTICS_EX_S and SRVM_SIGNAL_STATUS_S.
67 * It was obtained by comparing the way it was filled by the original code
68 */
69struct RECEPTION_STATISTICS_PER_SLICES_S {
70 u32 result;
71 u32 snr;
72 s32 inBandPower;
73 u32 tsPackets;
74 u32 etsPackets;
75 u32 constellation;
76 u32 hpCode;
77 u32 tpsSrvIndLP;
78 u32 tpsSrvIndHP;
79 u32 cellId;
80 u32 reason;
81 u32 requestId;
82 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
83
84 u32 BER; /* Post Viterbi BER [1E-5] */
85 s32 RSSI; /* dBm */
86 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
87
88 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
89 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
90
91 u32 BERBitCount; /* Total number of SYNC bits. */
92 u32 BERErrorCount; /* Number of erronous SYNC bits. */
93
94 s32 MRC_SNR; /* dB */
95 s32 MRC_InBandPwr; /* In band power in dBM */
96 s32 MRC_RSSI; /* dBm */
97};
98
99/* From smsdvb-debugfs.c */
100#ifdef CONFIG_SMS_SIANO_DEBUGFS
101
102int smsdvb_debugfs_create(struct smsdvb_client_t *client);
103void smsdvb_debugfs_release(struct smsdvb_client_t *client);
104int smsdvb_debugfs_register(void);
105void smsdvb_debugfs_unregister(void);
106
107#else
108
109static inline int smsdvb_debugfs_create(struct smsdvb_client_t *client)
110{
111 return 0;
112}
113
114static inline void smsdvb_debugfs_release(struct smsdvb_client_t *client) {}
115
116static inline int smsdvb_debugfs_register(void)
117{
118 return 0;
119};
120
121static inline void smsdvb_debugfs_unregister(void) {};
122
123#endif
124
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index acd3d1e82e03..def5e41405a4 100644
--- a/drivers/media/usb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
@@ -412,6 +412,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
412 412
413 smscore_set_board_id(dev->coredev, board_id); 413 smscore_set_board_id(dev->coredev, board_id);
414 414
415 dev->coredev->is_usb_device = true;
416
415 /* initialize urbs */ 417 /* initialize urbs */
416 for (i = 0; i < MAX_URBS; i++) { 418 for (i = 0; i < MAX_URBS; i++) {
417 dev->surbs[i].dev = dev; 419 dev->surbs[i].dev = dev;