hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/media/dvb-core/dvb_frontend.c
....@@ -1,6 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * dvb_frontend.c: DVB frontend tuning interface/thread
3
- *
44 *
55 * Copyright (C) 1999-2001 Ralph Metzler
66 * Marcus Metzler
....@@ -8,18 +8,6 @@
88 * for convergence integrated media GmbH
99 *
1010 * Copyright (C) 2004 Andrew de Quincey (tuning thread cleanup)
11
- *
12
- * This program is free software; you can redistribute it and/or
13
- * modify it under the terms of the GNU General Public License
14
- * as published by the Free Software Foundation; either version 2
15
- * of the License, or (at your option) any later version.
16
- *
17
- * This program is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- * GNU General Public License for more details.
21
- * To obtain the license, point your browser to
22
- * http://www.gnu.org/copyleft/gpl.html
2311 */
2412
2513 /* Enables DVBv3 compatibility bits at the headers */
....@@ -147,7 +135,7 @@
147135 struct dvb_frontend_private *fepriv = fe->frontend_priv;
148136
149137 if (fepriv)
150
- dvb_free_device(fepriv->dvbdev);
138
+ dvb_device_put(fepriv->dvbdev);
151139
152140 dvb_frontend_invoke_release(fe, fe->ops.release);
153141
....@@ -304,14 +292,22 @@
304292 }
305293
306294 if (events->eventw == events->eventr) {
307
- int ret;
295
+ struct wait_queue_entry wait;
296
+ int ret = 0;
308297
309298 if (flags & O_NONBLOCK)
310299 return -EWOULDBLOCK;
311300
312
- ret = wait_event_interruptible(events->wait_queue,
313
- dvb_frontend_test_event(fepriv, events));
314
-
301
+ init_waitqueue_entry(&wait, current);
302
+ add_wait_queue(&events->wait_queue, &wait);
303
+ while (!dvb_frontend_test_event(fepriv, events)) {
304
+ wait_woken(&wait, TASK_INTERRUPTIBLE, 0);
305
+ if (signal_pending(current)) {
306
+ ret = -ERESTARTSYS;
307
+ break;
308
+ }
309
+ }
310
+ remove_wait_queue(&events->wait_queue, &wait);
315311 if (ret < 0)
316312 return ret;
317313 }
....@@ -919,6 +915,9 @@
919915 dev_warn(fe->dvb->device,
920916 "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
921917 fe->dvb->num, fe->id);
918
+
919
+ dev_dbg(fe->dvb->device, "frequency interval: tuner: %u...%u, frontend: %u...%u",
920
+ tuner_min, tuner_max, frontend_min, frontend_max);
922921
923922 /* If the standard is for satellite, convert frequencies to kHz */
924923 switch (c->delivery_system) {
....@@ -1596,7 +1595,7 @@
15961595 *
15971596 * Provides emulation for delivery systems that are compatible with the old
15981597 * DVBv3 call. Among its usages, it provices support for ISDB-T, and allows
1599
- * using a DVB-S2 only frontend just like it were a DVB-S, if the frontent
1598
+ * using a DVB-S2 only frontend just like it were a DVB-S, if the frontend
16001599 * parameters are compatible with DVB-S spec.
16011600 */
16021601 static int emulate_delivery_system(struct dvb_frontend *fe, u32 delsys)
....@@ -2323,6 +2322,78 @@
23232322 return 0;
23242323 }
23252324
2325
+static int dvb_get_property(struct dvb_frontend *fe, struct file *file,
2326
+ struct dtv_properties *tvps)
2327
+{
2328
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
2329
+ struct dtv_property *tvp = NULL;
2330
+ struct dtv_frontend_properties getp;
2331
+ int i, err;
2332
+
2333
+ memcpy(&getp, &fe->dtv_property_cache, sizeof(getp));
2334
+
2335
+ dev_dbg(fe->dvb->device, "%s: properties.num = %d\n",
2336
+ __func__, tvps->num);
2337
+ dev_dbg(fe->dvb->device, "%s: properties.props = %p\n",
2338
+ __func__, tvps->props);
2339
+
2340
+ /*
2341
+ * Put an arbitrary limit on the number of messages that can
2342
+ * be sent at once
2343
+ */
2344
+ if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS)
2345
+ return -EINVAL;
2346
+
2347
+ tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
2348
+ if (IS_ERR(tvp))
2349
+ return PTR_ERR(tvp);
2350
+
2351
+ /*
2352
+ * Let's use our own copy of property cache, in order to
2353
+ * avoid mangling with DTV zigzag logic, as drivers might
2354
+ * return crap, if they don't check if the data is available
2355
+ * before updating the properties cache.
2356
+ */
2357
+ if (fepriv->state != FESTATE_IDLE) {
2358
+ err = dtv_get_frontend(fe, &getp, NULL);
2359
+ if (err < 0)
2360
+ goto out;
2361
+ }
2362
+ for (i = 0; i < tvps->num; i++) {
2363
+ err = dtv_property_process_get(fe, &getp,
2364
+ tvp + i, file);
2365
+ if (err < 0)
2366
+ goto out;
2367
+ }
2368
+
2369
+ if (copy_to_user((void __user *)tvps->props, tvp,
2370
+ tvps->num * sizeof(struct dtv_property))) {
2371
+ err = -EFAULT;
2372
+ goto out;
2373
+ }
2374
+
2375
+ err = 0;
2376
+out:
2377
+ kfree(tvp);
2378
+ return err;
2379
+}
2380
+
2381
+static int dvb_get_frontend(struct dvb_frontend *fe,
2382
+ struct dvb_frontend_parameters *p_out)
2383
+{
2384
+ struct dtv_frontend_properties getp;
2385
+
2386
+ /*
2387
+ * Let's use our own copy of property cache, in order to
2388
+ * avoid mangling with DTV zigzag logic, as drivers might
2389
+ * return crap, if they don't check if the data is available
2390
+ * before updating the properties cache.
2391
+ */
2392
+ memcpy(&getp, &fe->dtv_property_cache, sizeof(getp));
2393
+
2394
+ return dtv_get_frontend(fe, &getp, p_out);
2395
+}
2396
+
23262397 static int dvb_frontend_handle_ioctl(struct file *file,
23272398 unsigned int cmd, void *parg)
23282399 {
....@@ -2368,64 +2439,15 @@
23682439 err = 0;
23692440 break;
23702441 }
2371
- case FE_GET_PROPERTY: {
2372
- struct dtv_properties *tvps = parg;
2373
- struct dtv_property *tvp = NULL;
2374
- struct dtv_frontend_properties getp = fe->dtv_property_cache;
2375
-
2376
- dev_dbg(fe->dvb->device, "%s: properties.num = %d\n",
2377
- __func__, tvps->num);
2378
- dev_dbg(fe->dvb->device, "%s: properties.props = %p\n",
2379
- __func__, tvps->props);
2380
-
2381
- /*
2382
- * Put an arbitrary limit on the number of messages that can
2383
- * be sent at once
2384
- */
2385
- if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
2386
- return -EINVAL;
2387
-
2388
- tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
2389
- if (IS_ERR(tvp))
2390
- return PTR_ERR(tvp);
2391
-
2392
- /*
2393
- * Let's use our own copy of property cache, in order to
2394
- * avoid mangling with DTV zigzag logic, as drivers might
2395
- * return crap, if they don't check if the data is available
2396
- * before updating the properties cache.
2397
- */
2398
- if (fepriv->state != FESTATE_IDLE) {
2399
- err = dtv_get_frontend(fe, &getp, NULL);
2400
- if (err < 0) {
2401
- kfree(tvp);
2402
- return err;
2403
- }
2404
- }
2405
- for (i = 0; i < tvps->num; i++) {
2406
- err = dtv_property_process_get(fe, &getp,
2407
- tvp + i, file);
2408
- if (err < 0) {
2409
- kfree(tvp);
2410
- return err;
2411
- }
2412
- }
2413
-
2414
- if (copy_to_user((void __user *)tvps->props, tvp,
2415
- tvps->num * sizeof(struct dtv_property))) {
2416
- kfree(tvp);
2417
- return -EFAULT;
2418
- }
2419
- kfree(tvp);
2420
- err = 0;
2442
+ case FE_GET_PROPERTY:
2443
+ err = dvb_get_property(fe, file, parg);
24212444 break;
2422
- }
24232445
24242446 case FE_GET_INFO: {
24252447 struct dvb_frontend_info *info = parg;
24262448 memset(info, 0, sizeof(*info));
24272449
2428
- strcpy(info->name, fe->ops.info.name);
2450
+ strscpy(info->name, fe->ops.info.name, sizeof(info->name));
24292451 info->symbol_rate_min = fe->ops.info.symbol_rate_min;
24302452 info->symbol_rate_max = fe->ops.info.symbol_rate_max;
24312453 info->symbol_rate_tolerance = fe->ops.info.symbol_rate_tolerance;
....@@ -2557,7 +2579,6 @@
25572579 fepriv->tune_mode_flags = (unsigned long)parg;
25582580 err = 0;
25592581 break;
2560
-
25612582 /* DEPRECATED dish control ioctls */
25622583
25632584 case FE_DISHNETWORK_SEND_LEGACY_CMD:
....@@ -2590,8 +2611,8 @@
25902611 u8 last = 1;
25912612
25922613 if (dvb_frontend_debug)
2593
- dprintk("%s switch command: 0x%04lx\n",
2594
- __func__, swcmd);
2614
+ dprintk("switch command: 0x%04lx\n",
2615
+ swcmd);
25952616 nexttime = ktime_get_boottime();
25962617 if (dvb_frontend_debug)
25972618 tv[0] = nexttime;
....@@ -2614,8 +2635,8 @@
26142635 dvb_frontend_sleep_until(&nexttime, 8000);
26152636 }
26162637 if (dvb_frontend_debug) {
2617
- dprintk("%s(%d): switch delay (should be 32k followed by all 8k)\n",
2618
- __func__, fe->dvb->num);
2638
+ dprintk("(adapter %d): switch delay (should be 32k followed by all 8k)\n",
2639
+ fe->dvb->num);
26192640 for (i = 1; i < 10; i++)
26202641 pr_info("%d: %d\n", i,
26212642 (int)ktime_us_delta(tv[i], tv[i - 1]));
....@@ -2676,22 +2697,14 @@
26762697 break;
26772698 err = dtv_set_frontend(fe);
26782699 break;
2700
+
26792701 case FE_GET_EVENT:
26802702 err = dvb_frontend_get_event(fe, parg, file->f_flags);
26812703 break;
26822704
2683
- case FE_GET_FRONTEND: {
2684
- struct dtv_frontend_properties getp = fe->dtv_property_cache;
2685
-
2686
- /*
2687
- * Let's use our own copy of property cache, in order to
2688
- * avoid mangling with DTV zigzag logic, as drivers might
2689
- * return crap, if they don't check if the data is available
2690
- * before updating the properties cache.
2691
- */
2692
- err = dtv_get_frontend(fe, &getp, parg);
2705
+ case FE_GET_FRONTEND:
2706
+ err = dvb_get_frontend(fe, parg);
26932707 break;
2694
- }
26952708
26962709 default:
26972710 return -ENOTSUPP;
....@@ -2956,6 +2969,7 @@
29562969 .name = fe->ops.info.name,
29572970 #endif
29582971 };
2972
+ int ret;
29592973
29602974 dev_dbg(dvb->device, "%s:\n", __func__);
29612975
....@@ -2989,8 +3003,13 @@
29893003 "DVB: registering adapter %i frontend %i (%s)...\n",
29903004 fe->dvb->num, fe->id, fe->ops.info.name);
29913005
2992
- dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
3006
+ ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
29933007 fe, DVB_DEVICE_FRONTEND, 0);
3008
+ if (ret) {
3009
+ dvb_frontend_put(fe);
3010
+ mutex_unlock(&frontend_mutex);
3011
+ return ret;
3012
+ }
29943013
29953014 /*
29963015 * Initialize the cache to the proper values according with the