.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * dvb_frontend.c: DVB frontend tuning interface/thread |
---|
3 | | - * |
---|
4 | 4 | * |
---|
5 | 5 | * Copyright (C) 1999-2001 Ralph Metzler |
---|
6 | 6 | * Marcus Metzler |
---|
.. | .. |
---|
8 | 8 | * for convergence integrated media GmbH |
---|
9 | 9 | * |
---|
10 | 10 | * 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 |
---|
23 | 11 | */ |
---|
24 | 12 | |
---|
25 | 13 | /* Enables DVBv3 compatibility bits at the headers */ |
---|
.. | .. |
---|
920 | 908 | "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n", |
---|
921 | 909 | fe->dvb->num, fe->id); |
---|
922 | 910 | |
---|
| 911 | + dev_dbg(fe->dvb->device, "frequency interval: tuner: %u...%u, frontend: %u...%u", |
---|
| 912 | + tuner_min, tuner_max, frontend_min, frontend_max); |
---|
| 913 | + |
---|
923 | 914 | /* If the standard is for satellite, convert frequencies to kHz */ |
---|
924 | 915 | switch (c->delivery_system) { |
---|
925 | 916 | case SYS_DVBS: |
---|
.. | .. |
---|
1596 | 1587 | * |
---|
1597 | 1588 | * Provides emulation for delivery systems that are compatible with the old |
---|
1598 | 1589 | * 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 |
---|
| 1590 | + * using a DVB-S2 only frontend just like it were a DVB-S, if the frontend |
---|
1600 | 1591 | * parameters are compatible with DVB-S spec. |
---|
1601 | 1592 | */ |
---|
1602 | 1593 | static int emulate_delivery_system(struct dvb_frontend *fe, u32 delsys) |
---|
.. | .. |
---|
2323 | 2314 | return 0; |
---|
2324 | 2315 | } |
---|
2325 | 2316 | |
---|
| 2317 | +static int dvb_get_property(struct dvb_frontend *fe, struct file *file, |
---|
| 2318 | + struct dtv_properties *tvps) |
---|
| 2319 | +{ |
---|
| 2320 | + struct dvb_frontend_private *fepriv = fe->frontend_priv; |
---|
| 2321 | + struct dtv_property *tvp = NULL; |
---|
| 2322 | + struct dtv_frontend_properties getp; |
---|
| 2323 | + int i, err; |
---|
| 2324 | + |
---|
| 2325 | + memcpy(&getp, &fe->dtv_property_cache, sizeof(getp)); |
---|
| 2326 | + |
---|
| 2327 | + dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", |
---|
| 2328 | + __func__, tvps->num); |
---|
| 2329 | + dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", |
---|
| 2330 | + __func__, tvps->props); |
---|
| 2331 | + |
---|
| 2332 | + /* |
---|
| 2333 | + * Put an arbitrary limit on the number of messages that can |
---|
| 2334 | + * be sent at once |
---|
| 2335 | + */ |
---|
| 2336 | + if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS) |
---|
| 2337 | + return -EINVAL; |
---|
| 2338 | + |
---|
| 2339 | + tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); |
---|
| 2340 | + if (IS_ERR(tvp)) |
---|
| 2341 | + return PTR_ERR(tvp); |
---|
| 2342 | + |
---|
| 2343 | + /* |
---|
| 2344 | + * Let's use our own copy of property cache, in order to |
---|
| 2345 | + * avoid mangling with DTV zigzag logic, as drivers might |
---|
| 2346 | + * return crap, if they don't check if the data is available |
---|
| 2347 | + * before updating the properties cache. |
---|
| 2348 | + */ |
---|
| 2349 | + if (fepriv->state != FESTATE_IDLE) { |
---|
| 2350 | + err = dtv_get_frontend(fe, &getp, NULL); |
---|
| 2351 | + if (err < 0) |
---|
| 2352 | + goto out; |
---|
| 2353 | + } |
---|
| 2354 | + for (i = 0; i < tvps->num; i++) { |
---|
| 2355 | + err = dtv_property_process_get(fe, &getp, |
---|
| 2356 | + tvp + i, file); |
---|
| 2357 | + if (err < 0) |
---|
| 2358 | + goto out; |
---|
| 2359 | + } |
---|
| 2360 | + |
---|
| 2361 | + if (copy_to_user((void __user *)tvps->props, tvp, |
---|
| 2362 | + tvps->num * sizeof(struct dtv_property))) { |
---|
| 2363 | + err = -EFAULT; |
---|
| 2364 | + goto out; |
---|
| 2365 | + } |
---|
| 2366 | + |
---|
| 2367 | + err = 0; |
---|
| 2368 | +out: |
---|
| 2369 | + kfree(tvp); |
---|
| 2370 | + return err; |
---|
| 2371 | +} |
---|
| 2372 | + |
---|
| 2373 | +static int dvb_get_frontend(struct dvb_frontend *fe, |
---|
| 2374 | + struct dvb_frontend_parameters *p_out) |
---|
| 2375 | +{ |
---|
| 2376 | + struct dtv_frontend_properties getp; |
---|
| 2377 | + |
---|
| 2378 | + /* |
---|
| 2379 | + * Let's use our own copy of property cache, in order to |
---|
| 2380 | + * avoid mangling with DTV zigzag logic, as drivers might |
---|
| 2381 | + * return crap, if they don't check if the data is available |
---|
| 2382 | + * before updating the properties cache. |
---|
| 2383 | + */ |
---|
| 2384 | + memcpy(&getp, &fe->dtv_property_cache, sizeof(getp)); |
---|
| 2385 | + |
---|
| 2386 | + return dtv_get_frontend(fe, &getp, p_out); |
---|
| 2387 | +} |
---|
| 2388 | + |
---|
2326 | 2389 | static int dvb_frontend_handle_ioctl(struct file *file, |
---|
2327 | 2390 | unsigned int cmd, void *parg) |
---|
2328 | 2391 | { |
---|
.. | .. |
---|
2368 | 2431 | err = 0; |
---|
2369 | 2432 | break; |
---|
2370 | 2433 | } |
---|
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; |
---|
| 2434 | + case FE_GET_PROPERTY: |
---|
| 2435 | + err = dvb_get_property(fe, file, parg); |
---|
2421 | 2436 | break; |
---|
2422 | | - } |
---|
2423 | 2437 | |
---|
2424 | 2438 | case FE_GET_INFO: { |
---|
2425 | 2439 | struct dvb_frontend_info *info = parg; |
---|
2426 | 2440 | memset(info, 0, sizeof(*info)); |
---|
2427 | 2441 | |
---|
2428 | | - strcpy(info->name, fe->ops.info.name); |
---|
| 2442 | + strscpy(info->name, fe->ops.info.name, sizeof(info->name)); |
---|
2429 | 2443 | info->symbol_rate_min = fe->ops.info.symbol_rate_min; |
---|
2430 | 2444 | info->symbol_rate_max = fe->ops.info.symbol_rate_max; |
---|
2431 | 2445 | info->symbol_rate_tolerance = fe->ops.info.symbol_rate_tolerance; |
---|
.. | .. |
---|
2557 | 2571 | fepriv->tune_mode_flags = (unsigned long)parg; |
---|
2558 | 2572 | err = 0; |
---|
2559 | 2573 | break; |
---|
2560 | | - |
---|
2561 | 2574 | /* DEPRECATED dish control ioctls */ |
---|
2562 | 2575 | |
---|
2563 | 2576 | case FE_DISHNETWORK_SEND_LEGACY_CMD: |
---|
.. | .. |
---|
2590 | 2603 | u8 last = 1; |
---|
2591 | 2604 | |
---|
2592 | 2605 | if (dvb_frontend_debug) |
---|
2593 | | - dprintk("%s switch command: 0x%04lx\n", |
---|
2594 | | - __func__, swcmd); |
---|
| 2606 | + dprintk("switch command: 0x%04lx\n", |
---|
| 2607 | + swcmd); |
---|
2595 | 2608 | nexttime = ktime_get_boottime(); |
---|
2596 | 2609 | if (dvb_frontend_debug) |
---|
2597 | 2610 | tv[0] = nexttime; |
---|
.. | .. |
---|
2614 | 2627 | dvb_frontend_sleep_until(&nexttime, 8000); |
---|
2615 | 2628 | } |
---|
2616 | 2629 | if (dvb_frontend_debug) { |
---|
2617 | | - dprintk("%s(%d): switch delay (should be 32k followed by all 8k)\n", |
---|
2618 | | - __func__, fe->dvb->num); |
---|
| 2630 | + dprintk("(adapter %d): switch delay (should be 32k followed by all 8k)\n", |
---|
| 2631 | + fe->dvb->num); |
---|
2619 | 2632 | for (i = 1; i < 10; i++) |
---|
2620 | 2633 | pr_info("%d: %d\n", i, |
---|
2621 | 2634 | (int)ktime_us_delta(tv[i], tv[i - 1])); |
---|
.. | .. |
---|
2676 | 2689 | break; |
---|
2677 | 2690 | err = dtv_set_frontend(fe); |
---|
2678 | 2691 | break; |
---|
| 2692 | + |
---|
2679 | 2693 | case FE_GET_EVENT: |
---|
2680 | 2694 | err = dvb_frontend_get_event(fe, parg, file->f_flags); |
---|
2681 | 2695 | break; |
---|
2682 | 2696 | |
---|
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); |
---|
| 2697 | + case FE_GET_FRONTEND: |
---|
| 2698 | + err = dvb_get_frontend(fe, parg); |
---|
2693 | 2699 | break; |
---|
2694 | | - } |
---|
2695 | 2700 | |
---|
2696 | 2701 | default: |
---|
2697 | 2702 | return -ENOTSUPP; |
---|