| .. | .. |
|---|
| 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; |
|---|