All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: Question about 2 gp8psk patches I noticed, and possible bug.
       [not found] <CAA7C2qjXSkmmCB=zc7Y-Btpwzm_B=_ok0t6qMRuCy+gfrEhcMw@mail.gmail.com>
@ 2016-11-08 17:55 ` Mauro Carvalho Chehab
  2016-11-09  6:00   ` VDR User
  0 siblings, 1 reply; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-08 17:55 UTC (permalink / raw)
  To: VDR User; +Cc: linux-media

Em Sat, 5 Nov 2016 19:24:58 -0700
VDR User <user.vdr@gmail.com> escreveu:

> I have
> several different Genpix devices that use the gp8psk driver and in all
> cases the following happens when I unload it:
> 
> [494896.234616] usbcore: deregistering interface driver dvb_usb_gp8psk
> [494896.234712] ------------[ cut here ]------------
> [494896.234719] WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108
> module_put+0x57/0x70
> [494896.234720] Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core
> nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel
> snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore
> nvidia(PO) [last unloaded: rc_core]
> [494896.234732] CPU: 1 PID: 28102 Comm: rmmod Tainted: P        WC O
>  4.8.4-build.1 #1
> [494896.234733] Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
> [494896.234735]  00000000 c12ba080 00000000 00000000 c103ed6a c1616014
> 00000001 00006dc6
> [494896.234739]  c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff
> 00000000 f13f6a10
> [494896.234743]  f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7
> f80ca4d0 c109f617
> [494896.234746] Call Trace:
> [494896.234753]  [<c12ba080>] ? dump_stack+0x44/0x64
> [494896.234756]  [<c103ed6a>] ? __warn+0xfa/0x120
> [494896.234758]  [<c109e8a7>] ? module_put+0x57/0x70
> [494896.234760]  [<c109e8a7>] ? module_put+0x57/0x70
> [494896.234762]  [<c103ee33>] ? warn_slowpath_null+0x23/0x30
> [494896.234763]  [<c109e8a7>] ? module_put+0x57/0x70
> [494896.234766]  [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460
> [dvb_usb_gp8psk]
> [494896.234769]  [<c109f617>] ? symbol_put_addr+0x27/0x50
> [494896.234771]  [<f80bc9ca>] ?
> dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]
> [494896.234773]  [<f80bb3bf>] ? dvb_usb_exit+0x2f/0xd0 [dvb_usb]
> [494896.234776]  [<c13d03bc>] ? usb_disable_endpoint+0x7c/0xb0
> [494896.234778]  [<f80bb48a>] ? dvb_usb_device_exit+0x2a/0x50 [dvb_usb]
> [494896.234780]  [<c13d2882>] ? usb_unbind_interface+0x62/0x250
> [494896.234782]  [<c136b514>] ? __pm_runtime_idle+0x44/0x70
> [494896.234785]  [<c13620d8>] ? __device_release_driver+0x78/0x120
> [494896.234787]  [<c1362907>] ? driver_detach+0x87/0x90
> [494896.234789]  [<c1361c48>] ? bus_remove_driver+0x38/0x90
> [494896.234791]  [<c13d1c18>] ? usb_deregister+0x58/0xb0
> [494896.234793]  [<c109fbb0>] ? SyS_delete_module+0x130/0x1f0
> [494896.234796]  [<c1055654>] ? task_work_run+0x64/0x80
> [494896.234798]  [<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90
> [494896.234800]  [<c10013f0>] ? do_fast_syscall_32+0x80/0x130
> [494896.234803]  [<c1549f43>] ? sysenter_past_esp+0x40/0x6a
> [494896.234805] ---[ end trace 6ebc60ef3981792f ]---
> [494896.235890] dvb-usb: Genpix SkyWalker-2 DVB-S receiver
> successfully deinitialized and disconnected.

I suspect that this is due to a race condition at device unregister.
could you please try the enclosed patch?

gp8psk: unregister gp8psk-fe early

Letting gp8psk-fe to unregister late can cause race issues.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>


diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 2829e3082d15..04ea2bbbe5ae 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -270,6 +270,32 @@ static int gp8psk_usb_probe(struct usb_interface *intf,
 	return ret;
 }
 
+static void gp8psk_usb_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	struct dvb_usb_adapter *adap;
+	int i, n;
+
+	/*
+	 * As gsp8psk-fe can call back this driver, in order to do URB
+	 * transfers, we need to manually exit the frontend earlier.
+	 */
+	for (n = 0; n < d->num_adapters_initialized; n++) {
+		adap = &d->adapter[n];
+		i = adap->num_frontends_initialized - 1;
+
+		for (; i >= 0; i--) {
+			if (adap->fe_adap[i].fe != NULL) {
+				dvb_unregister_frontend(adap->fe_adap[i].fe);
+				dvb_frontend_detach(adap->fe_adap[i].fe);
+			}
+		}
+		adap->num_frontends_initialized = 0;
+	}
+
+	dvb_usb_device_exit(intf);
+}
+
 static struct usb_device_id gp8psk_usb_table [] = {
 	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
 	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
@@ -338,7 +364,7 @@ static struct dvb_usb_device_properties gp8psk_properties = {
 static struct usb_driver gp8psk_usb_driver = {
 	.name		= "dvb_usb_gp8psk",
 	.probe		= gp8psk_usb_probe,
-	.disconnect = dvb_usb_device_exit,
+	.disconnect	= gp8psk_usb_disconnect,
 	.id_table	= gp8psk_usb_table,
 };
 

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-08 17:55 ` Question about 2 gp8psk patches I noticed, and possible bug Mauro Carvalho Chehab
@ 2016-11-09  6:00   ` VDR User
  2016-11-09  9:33     ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 19+ messages in thread
From: VDR User @ 2016-11-09  6:00 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: mailing list: linux-media

Hi Mauro,

Unfortunately the patch doesn't seem to have solved the problem. I do
have the kernel recompiled with debug enabled though per your irc msg.
dmesg gives me:

[   70.741073] usbcore: deregistering interface driver dvb_usb_gp8psk
[   70.741165] ------------[ cut here ]------------
[   70.741172] WARNING: CPU: 1 PID: 2119 at kernel/module.c:1108
module_put+0x67/0x80
[   70.741174] Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core
nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel
snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore
nvidia(PO)
[   70.741186] CPU: 1 PID: 2119 Comm: rmmod Tainted: P           O
4.8.4-build.2 #1
[   70.741187] Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
[   70.741189]  00000000 c12c15f0 00000000 00000000 c103fc7a c161ecc0
00000001 00000847
[   70.741194]  c161e50f 00000454 c10a4b87 c10a4b87 00000009 fb090cc0
00000000 00000000
[   70.741197]  f4e72000 c103fd43 00000009 00000000 00000000 c10a4b87
fb08f6a0 c10a58fa
[   70.741202] Call Trace:
[   70.741206]  [<c12c15f0>] ? dump_stack+0x44/0x64
[   70.741209]  [<c103fc7a>] ? __warn+0xfa/0x120
[   70.741211]  [<c10a4b87>] ? module_put+0x67/0x80
[   70.741213]  [<c10a4b87>] ? module_put+0x67/0x80
[   70.741215]  [<c103fd43>] ? warn_slowpath_null+0x23/0x30
[   70.741217]  [<c10a4b87>] ? module_put+0x67/0x80
[   70.741221]  [<fb08f6a0>] ? gp8psk_fe_set_frontend+0x460/0x460
[dvb_usb_gp8psk]
[   70.741223]  [<c10a58fa>] ? symbol_put_addr+0x2a/0x50
[   70.741225]  [<fb08e04e>] ? gp8psk_usb_disconnect+0x4e/0x90 [dvb_usb_gp8psk]
[   70.741229]  [<c13da272>] ? usb_unbind_interface+0x62/0x250
[   70.741233]  [<c1551f3f>] ? _raw_spin_unlock_irqrestore+0xf/0x30
[   70.741235]  [<c1372ea4>] ? __pm_runtime_idle+0x44/0x70
[   70.741239]  [<c1369a68>] ? __device_release_driver+0x78/0x120
[   70.741241]  [<c136a297>] ? driver_detach+0x87/0x90
[   70.741243]  [<c13695d8>] ? bus_remove_driver+0x38/0x90
[   70.741245]  [<c13d9608>] ? usb_deregister+0x58/0xb0
[   70.741248]  [<c10a5eb0>] ? SyS_delete_module+0x130/0x1f0
[   70.741251]  [<c1036200>] ? __do_page_fault+0x1a0/0x440
[   70.741253]  [<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90
[   70.741254]  [<c10013f0>] ? do_fast_syscall_32+0x80/0x130
[   70.741257]  [<c1552403>] ? sysenter_past_esp+0x40/0x6a
[   70.741259] ---[ end trace a387b7eddb538bfb ]---
[   70.743654] dvb-usb: Genpix SkyWalker-2 DVB-S receiver successfully
deinitialized and disconnected.


I read the Bug Hunting url but it's still not clear to me which line
from that dmesg text I should be focused on. It would suggest the
first line (dump_stack+0x44/0x64) but you pointed to
gp8psk_fe_set_frontend so I'm not sure what to do next. When I go into
gdb I see:

gdb $(find /lib/modules/$(uname -r) -name dvb-usb-gp8psk.ko)
...
Reading symbols from
/lib/modules/4.8.4-build.2/kernel/drivers/media/usb/dvb-usb/dvb-usb-gp8psk.ko...(no
debugging symbols found)...done.
(gdb)

gdb /usr/src/linux/vmlinux
...
Reading symbols from /usr/src/linux/vmlinux...done.
(gdb)
(gdb)

"No debugging symbols found" doesn't sound good, but DEBUG is enabled:

$ grep "^CONFIG_DEBUG" /usr/src/linux/.config
CONFIG_DEBUG_RODATA=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_BUGVERBOSE=y



On Tue, Nov 8, 2016 at 9:55 AM, Mauro Carvalho Chehab
<mchehab@s-opensource.com> wrote:
> Em Sat, 5 Nov 2016 19:24:58 -0700
> VDR User <user.vdr@gmail.com> escreveu:
>
>> I have
>> several different Genpix devices that use the gp8psk driver and in all
>> cases the following happens when I unload it:
>>
>> [494896.234616] usbcore: deregistering interface driver dvb_usb_gp8psk
>> [494896.234712] ------------[ cut here ]------------
>> [494896.234719] WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108
>> module_put+0x57/0x70
>> [494896.234720] Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core
>> nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel
>> snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore
>> nvidia(PO) [last unloaded: rc_core]
>> [494896.234732] CPU: 1 PID: 28102 Comm: rmmod Tainted: P        WC O
>>  4.8.4-build.1 #1
>> [494896.234733] Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
>> [494896.234735]  00000000 c12ba080 00000000 00000000 c103ed6a c1616014
>> 00000001 00006dc6
>> [494896.234739]  c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff
>> 00000000 f13f6a10
>> [494896.234743]  f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7
>> f80ca4d0 c109f617
>> [494896.234746] Call Trace:
>> [494896.234753]  [<c12ba080>] ? dump_stack+0x44/0x64
>> [494896.234756]  [<c103ed6a>] ? __warn+0xfa/0x120
>> [494896.234758]  [<c109e8a7>] ? module_put+0x57/0x70
>> [494896.234760]  [<c109e8a7>] ? module_put+0x57/0x70
>> [494896.234762]  [<c103ee33>] ? warn_slowpath_null+0x23/0x30
>> [494896.234763]  [<c109e8a7>] ? module_put+0x57/0x70
>> [494896.234766]  [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460
>> [dvb_usb_gp8psk]
>> [494896.234769]  [<c109f617>] ? symbol_put_addr+0x27/0x50
>> [494896.234771]  [<f80bc9ca>] ?
>> dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]
>> [494896.234773]  [<f80bb3bf>] ? dvb_usb_exit+0x2f/0xd0 [dvb_usb]
>> [494896.234776]  [<c13d03bc>] ? usb_disable_endpoint+0x7c/0xb0
>> [494896.234778]  [<f80bb48a>] ? dvb_usb_device_exit+0x2a/0x50 [dvb_usb]
>> [494896.234780]  [<c13d2882>] ? usb_unbind_interface+0x62/0x250
>> [494896.234782]  [<c136b514>] ? __pm_runtime_idle+0x44/0x70
>> [494896.234785]  [<c13620d8>] ? __device_release_driver+0x78/0x120
>> [494896.234787]  [<c1362907>] ? driver_detach+0x87/0x90
>> [494896.234789]  [<c1361c48>] ? bus_remove_driver+0x38/0x90
>> [494896.234791]  [<c13d1c18>] ? usb_deregister+0x58/0xb0
>> [494896.234793]  [<c109fbb0>] ? SyS_delete_module+0x130/0x1f0
>> [494896.234796]  [<c1055654>] ? task_work_run+0x64/0x80
>> [494896.234798]  [<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90
>> [494896.234800]  [<c10013f0>] ? do_fast_syscall_32+0x80/0x130
>> [494896.234803]  [<c1549f43>] ? sysenter_past_esp+0x40/0x6a
>> [494896.234805] ---[ end trace 6ebc60ef3981792f ]---
>> [494896.235890] dvb-usb: Genpix SkyWalker-2 DVB-S receiver
>> successfully deinitialized and disconnected.
>
> I suspect that this is due to a race condition at device unregister.
> could you please try the enclosed patch?
>
> gp8psk: unregister gp8psk-fe early
>
> Letting gp8psk-fe to unregister late can cause race issues.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
>
>
> diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
> index 2829e3082d15..04ea2bbbe5ae 100644
> --- a/drivers/media/usb/dvb-usb/gp8psk.c
> +++ b/drivers/media/usb/dvb-usb/gp8psk.c
> @@ -270,6 +270,32 @@ static int gp8psk_usb_probe(struct usb_interface *intf,
>         return ret;
>  }
>
> +static void gp8psk_usb_disconnect(struct usb_interface *intf)
> +{
> +       struct dvb_usb_device *d = usb_get_intfdata(intf);
> +       struct dvb_usb_adapter *adap;
> +       int i, n;
> +
> +       /*
> +        * As gsp8psk-fe can call back this driver, in order to do URB
> +        * transfers, we need to manually exit the frontend earlier.
> +        */
> +       for (n = 0; n < d->num_adapters_initialized; n++) {
> +               adap = &d->adapter[n];
> +               i = adap->num_frontends_initialized - 1;
> +
> +               for (; i >= 0; i--) {
> +                       if (adap->fe_adap[i].fe != NULL) {
> +                               dvb_unregister_frontend(adap->fe_adap[i].fe);
> +                               dvb_frontend_detach(adap->fe_adap[i].fe);
> +                       }
> +               }
> +               adap->num_frontends_initialized = 0;
> +       }
> +
> +       dvb_usb_device_exit(intf);
> +}
> +
>  static struct usb_device_id gp8psk_usb_table [] = {
>             { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
>             { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
> @@ -338,7 +364,7 @@ static struct dvb_usb_device_properties gp8psk_properties = {
>  static struct usb_driver gp8psk_usb_driver = {
>         .name           = "dvb_usb_gp8psk",
>         .probe          = gp8psk_usb_probe,
> -       .disconnect = dvb_usb_device_exit,
> +       .disconnect     = gp8psk_usb_disconnect,
>         .id_table       = gp8psk_usb_table,
>  };
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-09  6:00   ` VDR User
@ 2016-11-09  9:33     ` Mauro Carvalho Chehab
  2016-11-09 15:37       ` VDR User
  0 siblings, 1 reply; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-09  9:33 UTC (permalink / raw)
  To: VDR User; +Cc: mailing list: linux-media

Em Tue, 8 Nov 2016 22:00:41 -0800
VDR User <user.vdr@gmail.com> escreveu:

> Hi Mauro,
> 
> Unfortunately the patch doesn't seem to have solved the problem. I do
> have the kernel recompiled with debug enabled though per your irc msg.
> dmesg gives me:
> 
> [   70.741073] usbcore: deregistering interface driver dvb_usb_gp8psk
> [   70.741165] ------------[ cut here ]------------
> [   70.741172] WARNING: CPU: 1 PID: 2119 at kernel/module.c:1108
> module_put+0x67/0x80
> [   70.741174] Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core
> nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel
> snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore
> nvidia(PO)
> [   70.741186] CPU: 1 PID: 2119 Comm: rmmod Tainted: P           O
> 4.8.4-build.2 #1
> [   70.741187] Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
> [   70.741189]  00000000 c12c15f0 00000000 00000000 c103fc7a c161ecc0
> 00000001 00000847
> [   70.741194]  c161e50f 00000454 c10a4b87 c10a4b87 00000009 fb090cc0
> 00000000 00000000
> [   70.741197]  f4e72000 c103fd43 00000009 00000000 00000000 c10a4b87
> fb08f6a0 c10a58fa
> [   70.741202] Call Trace:
> [   70.741206]  [<c12c15f0>] ? dump_stack+0x44/0x64
> [   70.741209]  [<c103fc7a>] ? __warn+0xfa/0x120
> [   70.741211]  [<c10a4b87>] ? module_put+0x67/0x80
> [   70.741213]  [<c10a4b87>] ? module_put+0x67/0x80
> [   70.741215]  [<c103fd43>] ? warn_slowpath_null+0x23/0x30
> [   70.741217]  [<c10a4b87>] ? module_put+0x67/0x80
> [   70.741221]  [<fb08f6a0>] ? gp8psk_fe_set_frontend+0x460/0x460
> [dvb_usb_gp8psk]
> [   70.741223]  [<c10a58fa>] ? symbol_put_addr+0x2a/0x50
> [   70.741225]  [<fb08e04e>] ? gp8psk_usb_disconnect+0x4e/0x90 [dvb_usb_gp8psk]

Ok, it is running your new driver.

> [   70.741229]  [<c13da272>] ? usb_unbind_interface+0x62/0x250
> [   70.741233]  [<c1551f3f>] ? _raw_spin_unlock_irqrestore+0xf/0x30
> [   70.741235]  [<c1372ea4>] ? __pm_runtime_idle+0x44/0x70
> [   70.741239]  [<c1369a68>] ? __device_release_driver+0x78/0x120
> [   70.741241]  [<c136a297>] ? driver_detach+0x87/0x90
> [   70.741243]  [<c13695d8>] ? bus_remove_driver+0x38/0x90
> [   70.741245]  [<c13d9608>] ? usb_deregister+0x58/0xb0
> [   70.741248]  [<c10a5eb0>] ? SyS_delete_module+0x130/0x1f0
> [   70.741251]  [<c1036200>] ? __do_page_fault+0x1a0/0x440
> [   70.741253]  [<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90
> [   70.741254]  [<c10013f0>] ? do_fast_syscall_32+0x80/0x130
> [   70.741257]  [<c1552403>] ? sysenter_past_esp+0x40/0x6a
> [   70.741259] ---[ end trace a387b7eddb538bfb ]---
> [   70.743654] dvb-usb: Genpix SkyWalker-2 DVB-S receiver successfully
> deinitialized and disconnected.
> 
> 
> I read the Bug Hunting url but it's still not clear to me which line
> from that dmesg text I should be focused on. It would suggest the
> first line (dump_stack+0x44/0x64) but you pointed to
> gp8psk_fe_set_frontend so I'm not sure what to do next. 

I wrote some patches a few days ago improving bug hunting. Just updated
it at fedorapeople:
	https://mchehab.fedorapeople.org/kernel_docs/admin-guide/bug-hunting.html

Basically, each line on the above is a function. dump_stack() is the one
that generates the above dump. So, not useful. Assuming that the driver
core at the Kernel is ok (with is usually a good assumption), we can
exclude __warn() and module_put(), warn_slowpath_null() and other similar
functions, focusing on the ones inside gp8psk module.

> When I go into
> gdb I see:
> 
> gdb $(find /lib/modules/$(uname -r) -name dvb-usb-gp8psk.ko)
> ...
> Reading symbols from
> /lib/modules/4.8.4-build.2/kernel/drivers/media/usb/dvb-usb/dvb-usb-gp8psk.ko...(no
> debugging symbols found)...done.
> (gdb)
> 
> gdb /usr/src/linux/vmlinux
> ...
> Reading symbols from /usr/src/linux/vmlinux...done.
> (gdb)
> (gdb)
> 
> "No debugging symbols found" doesn't sound good,

Yes. Clearly, it was unable to read the symbols. Depending on the
way you built the Kernel, though, the symbols may have been
stripped at the install dirs (using the strip command). Fedora builds do
that, placing the symbols on a separate package, that can be installed in
separate (kernel-debug).

The safest way to get the symbols is by loading 
dvb-usb-gp8psk.ko from the directory where you compiled the
Kernel, instead of from /lib/modules/.



> but DEBUG is enabled:
> 
> $ grep "^CONFIG_DEBUG" /usr/src/linux/.config
> CONFIG_DEBUG_RODATA=y
> CONFIG_DEBUG_INFO=y
> CONFIG_DEBUG_FS=y
> CONFIG_DEBUG_KERNEL=y
> CONFIG_DEBUG_MEMORY_INIT=y
> CONFIG_DEBUG_PREEMPT=y
> CONFIG_DEBUG_BUGVERBOSE=y

Yes, you should have symbols there.

What disturbs me is why gp8psk_fe_set_frontend() is on that stack trace.
It doesn't make much sense, except if you're trying to open the frontend
while removing the module. Anyway, I added a few printks and changed
something at the dvb_frontend core to test some things.

Please test the enclosed patch. It replaces the one I sent you before.

Thanks,
Mauro

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 98edf46b22d0..a43ac8f36895 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2726,6 +2726,9 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
 	mutex_lock(&frontend_mutex);
+
+	/* We should not accept open() anymore for the frontend */
+	fe->exit = DVB_FE_DEVICE_REMOVED;
 	dvb_frontend_stop (fe);
 	dvb_unregister_device (fepriv->dvbdev);
 
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index cede0d8b0f8a..bb01f1dc8ed0 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -270,6 +270,35 @@ static int gp8psk_usb_probe(struct usb_interface *intf,
 	return ret;
 }
 
+static void gp8psk_usb_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	struct dvb_usb_adapter *adap;
+	int i, n;
+
+	/*
+	 * As gsp8psk-fe can call back this driver, in order to do URB
+	 * transfers, we need to manually exit the frontend earlier.
+	 */
+	for (n = 0; n < d->num_adapters_initialized; n++) {
+		adap = &d->adapter[n];
+		i = adap->num_frontends_initialized - 1;
+
+		for (; i >= 0; i--) {
+			if (adap->fe_adap[i].fe != NULL) {
+				printk("gp8psk: unregistering fe%d\n", i);
+				dvb_unregister_frontend(adap->fe_adap[i].fe);
+				printk("gp8psk: detaching fe%d\n", i);
+				dvb_frontend_detach(adap->fe_adap[i].fe);
+			}
+		}
+		adap->num_frontends_initialized = 0;
+	}
+
+	printk("gp8psk: calling dvb_usb_device_exit\n");
+	dvb_usb_device_exit(intf);
+}
+
 static struct usb_device_id gp8psk_usb_table [] = {
 	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
 	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
@@ -338,7 +367,7 @@ static struct dvb_usb_device_properties gp8psk_properties = {
 static struct usb_driver gp8psk_usb_driver = {
 	.name		= "dvb_usb_gp8psk",
 	.probe		= gp8psk_usb_probe,
-	.disconnect = dvb_usb_device_exit,
+	.disconnect	= gp8psk_usb_disconnect,
 	.id_table	= gp8psk_usb_table,
 };
 


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-09  9:33     ` Mauro Carvalho Chehab
@ 2016-11-09 15:37       ` VDR User
  2016-11-09 15:49         ` VDR User
  0 siblings, 1 reply; 19+ messages in thread
From: VDR User @ 2016-11-09 15:37 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: mailing list: linux-media

Hi Mauro,

Here are the results after testing the latest patch:

[33922.643770] usbcore: deregistering interface driver dvb_usb_gp8psk
[33922.643789] gp8psk: unregistering fe0
[33922.643865] gp8psk: detaching fe0
[33922.643868] ------------[ cut here ]------------
[33922.643875] WARNING: CPU: 1 PID: 8895 at kernel/module.c:1108
module_put+0x67/0x80
[33922.643876] Modules linked in: dvb_usb_gp8psk(O-) dvb_usb(O)
dvb_core(O) nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi
snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer
snd soundcore nvidia(PO) [last unloaded: dvb_core]
[33922.643890] CPU: 1 PID: 8895 Comm: rmmod Tainted: P        WC O
4.8.4-build.2 #1
[33922.643891] Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
[33922.643893]  00000000 c12c15f0 00000000 00000000 c103fc7a c161ecc0
00000001 000022bf
[33922.643897]  c161e50f 00000454 c10a4b87 c10a4b87 00000009 f804fd80
00000000 00000000
[33922.643901]  f3cca000 c103fd43 00000009 00000000 00000000 c10a4b87
f804e6e0 c10a58fa
[33922.643905] Call Trace:
[33922.643909]  [<c12c15f0>] ? dump_stack+0x44/0x64
[33922.643913]  [<c103fc7a>] ? __warn+0xfa/0x120
[33922.643915]  [<c10a4b87>] ? module_put+0x67/0x80
[33922.643917]  [<c10a4b87>] ? module_put+0x67/0x80
[33922.643919]  [<c103fd43>] ? warn_slowpath_null+0x23/0x30
[33922.643921]  [<c10a4b87>] ? module_put+0x67/0x80
[33922.643924]  [<f804e6e0>] ? gp8psk_fe_set_frontend+0x460/0x460
[dvb_usb_gp8psk]
[33922.643927]  [<c10a58fa>] ? symbol_put_addr+0x2a/0x50
[33922.643929]  [<f804d0b9>] ? gp8psk_usb_disconnect+0xb9/0xd0 [dvb_usb_gp8psk]
[33922.643932]  [<c13da272>] ? usb_unbind_interface+0x62/0x250
[33922.643936]  [<c1551f3f>] ? _raw_spin_unlock_irqrestore+0xf/0x30
[33922.643939]  [<c1372ea4>] ? __pm_runtime_idle+0x44/0x70
[33922.643943]  [<c1369a68>] ? __device_release_driver+0x78/0x120
[33922.643945]  [<c136a297>] ? driver_detach+0x87/0x90
[33922.643947]  [<c13695d8>] ? bus_remove_driver+0x38/0x90
[33922.643949]  [<c13d9608>] ? usb_deregister+0x58/0xb0
[33922.643951]  [<c10a5eb0>] ? SyS_delete_module+0x130/0x1f0
[33922.643954]  [<c1036200>] ? __do_page_fault+0x1a0/0x440
[33922.643956]  [<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90
[33922.643958]  [<c10013f0>] ? do_fast_syscall_32+0x80/0x130
[33922.643961]  [<c1552403>] ? sysenter_past_esp+0x40/0x6a
[33922.643962] ---[ end trace a387b7eddb538bfe ]---
[33922.643963] gp8psk: calling dvb_usb_device_exit
[33922.646462] dvb-usb: Genpix SkyWalker-2 DVB-S receiver successfully
deinitialized and disconnected.

$ gdb /usr/src/linux/drivers/media/usb/dvb-usb/dvb-usb-gp8psk.ko
GNU gdb (Debian 7.11.1-2) 7.11.1
...
Reading symbols from
/usr/src/linux/drivers/media/usb/dvb-usb/dvb-usb-gp8psk.ko...done.
(gdb) l *gp8psk_fe_set_frontend+0x460
0x1710 is in gp8psk_fe_release (drivers/media/usb/dvb-usb/gp8psk-fe.c:325).
320     }
321
322     static void gp8psk_fe_release(struct dvb_frontend* fe)
323     {
324             struct gp8psk_fe_state *state = fe->demodulator_priv;
325             kfree(state);
326     }
327
328     static struct dvb_frontend_ops gp8psk_fe_ops;
329
(gdb) l *gp8psk_usb_disconnect+0xb9
0xe9 is in gp8psk_usb_disconnect (drivers/media/usb/dvb-usb/gp8psk.c:432).
427                     for (; i >= 0; i--) {
428                             if (adap->fe_adap[i].fe != NULL) {
429                                     printk("gp8psk: unregistering
fe%d\n", i);
430
dvb_unregister_frontend(adap->fe_adap[i].fe);
431                                     printk("gp8psk: detaching fe%d\n", i);
432
dvb_frontend_detach(adap->fe_adap[i].fe);
433                             }
434                     }
435                     adap->num_frontends_initialized = 0;
436             }

Thanks,
Derek

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-09 15:37       ` VDR User
@ 2016-11-09 15:49         ` VDR User
  2016-11-09 17:35           ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 19+ messages in thread
From: VDR User @ 2016-11-09 15:49 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: mailing list: linux-media

$ gdb /usr/src/linux/vmlinux
GNU gdb (Debian 7.11.1-2) 7.11.1
...
Reading symbols from /usr/src/linux/vmlinux...done.
(gdb) l *module_put+0x67
0xc10a4b87 is in module_put (kernel/module.c:1108).
1103            int ret;
1104
1105            if (module) {
1106                    preempt_disable();
1107                    ret = atomic_dec_if_positive(&module->refcnt);
1108                    WARN_ON(ret < 0);       /* Failed to put refcount */
1109                    trace_module_put(module, _RET_IP_);
1110                    preempt_enable();
1111            }
1112    }

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-09 15:49         ` VDR User
@ 2016-11-09 17:35           ` Mauro Carvalho Chehab
  2016-11-10  1:03             ` VDR User
  0 siblings, 1 reply; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-09 17:35 UTC (permalink / raw)
  To: VDR User; +Cc: LMML

Em Wed, 9 Nov 2016 07:49:43 -0800
VDR User <user.vdr@gmail.com> escreveu:

> $ gdb /usr/src/linux/vmlinux
> GNU gdb (Debian 7.11.1-2) 7.11.1
> ...
> Reading symbols from /usr/src/linux/vmlinux...done.
> (gdb) l *module_put+0x67
> 0xc10a4b87 is in module_put (kernel/module.c:1108).
> 1103            int ret;
> 1104
> 1105            if (module) {
> 1106                    preempt_disable();
> 1107                    ret = atomic_dec_if_positive(&module->refcnt);
> 1108                    WARN_ON(ret < 0);       /* Failed to put refcount */
> 1109                    trace_module_put(module, _RET_IP_);
> 1110                    preempt_enable();
> 1111            }
> 1112    }

OK, I guess we've made progress. Please try the enclosed patch.

Regards,
Mauro

[media] gp8psk: Fix DVB frontend attach

it should be calling module_get() at attach, as otherwise
module_put() will crash.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>


Thanks,
Mauro

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-09 17:35           ` Mauro Carvalho Chehab
@ 2016-11-10  1:03             ` VDR User
  2016-11-10  8:07               ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 19+ messages in thread
From: VDR User @ 2016-11-10  1:03 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: LMML

>> (gdb) l *module_put+0x67
>> 0xc10a4b87 is in module_put (kernel/module.c:1108).
>> 1103            int ret;
>> 1104
>> 1105            if (module) {
>> 1106                    preempt_disable();
>> 1107                    ret = atomic_dec_if_positive(&module->refcnt);
>> 1108                    WARN_ON(ret < 0);       /* Failed to put refcount */
>> 1109                    trace_module_put(module, _RET_IP_);
>> 1110                    preempt_enable();
>> 1111            }
>> 1112    }
>
> OK, I guess we've made progress. Please try the enclosed patch.
>
> Regards,
> Mauro
>
> [media] gp8psk: Fix DVB frontend attach
>
> it should be calling module_get() at attach, as otherwise
> module_put() will crash.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

I think you forgot the patch. :)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-10  1:03             ` VDR User
@ 2016-11-10  8:07               ` Mauro Carvalho Chehab
  2016-11-10 15:01                 ` VDR User
  0 siblings, 1 reply; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-10  8:07 UTC (permalink / raw)
  To: VDR User; +Cc: LMML

Em Wed, 9 Nov 2016 17:03:52 -0800
VDR User <user.vdr@gmail.com> escreveu:

> >> (gdb) l *module_put+0x67
> >> 0xc10a4b87 is in module_put (kernel/module.c:1108).
> >> 1103            int ret;
> >> 1104
> >> 1105            if (module) {
> >> 1106                    preempt_disable();
> >> 1107                    ret = atomic_dec_if_positive(&module->refcnt);
> >> 1108                    WARN_ON(ret < 0);       /* Failed to put refcount */
> >> 1109                    trace_module_put(module, _RET_IP_);
> >> 1110                    preempt_enable();
> >> 1111            }
> >> 1112    }  
> >
> > OK, I guess we've made progress. Please try the enclosed patch.
> >
> > Regards,
> > Mauro
> >
> > [media] gp8psk: Fix DVB frontend attach
> >
> > it should be calling module_get() at attach, as otherwise
> > module_put() will crash.
> >
> > Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>  
> 
> I think you forgot the patch. :)

commit 0c979a12309af49894bb1dc60e747c3cd53fa888
Author: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Date:   Wed Nov 9 15:33:17 2016 -0200

    [media] gp8psk: Fix DVB frontend attach
    
    it should be calling module_get() at attach, as otherwise
    module_put() will crash.
    
    Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index cede0d8b0f8a..24eb6c6c8e24 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -250,7 +250,7 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 
 static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
+	adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, adap->dev);
 	return 0;
 }

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-10  8:07               ` Mauro Carvalho Chehab
@ 2016-11-10 15:01                 ` VDR User
  2016-11-11 12:49                   ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 19+ messages in thread
From: VDR User @ 2016-11-10 15:01 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: LMML

> commit 0c979a12309af49894bb1dc60e747c3cd53fa888
> Author: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> Date:   Wed Nov 9 15:33:17 2016 -0200
>
>     [media] gp8psk: Fix DVB frontend attach
>
>     it should be calling module_get() at attach, as otherwise
>     module_put() will crash.
>
>     Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
>
> diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
> index cede0d8b0f8a..24eb6c6c8e24 100644
> --- a/drivers/media/usb/dvb-usb/gp8psk.c
> +++ b/drivers/media/usb/dvb-usb/gp8psk.c
> @@ -250,7 +250,7 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
>
>  static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
>  {
> -       adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
> +       adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, adap->dev);
>         return 0;
>  }

This gives:

[119150.498863] DVB: Unable to find symbol gp8psk_fe_attach()
[119150.498928] dvb-usb: no frontend was attached by 'Genpix
SkyWalker-2 DVB-S receiver'

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-10 15:01                 ` VDR User
@ 2016-11-11 12:49                   ` Mauro Carvalho Chehab
  2016-11-11 15:33                     ` VDR User
  0 siblings, 1 reply; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-11 12:49 UTC (permalink / raw)
  To: VDR User; +Cc: Mauro Carvalho Chehab, LMML

Em Thu, 10 Nov 2016 07:01:44 -0800
VDR User <user.vdr@gmail.com> escreveu:

> > commit 0c979a12309af49894bb1dc60e747c3cd53fa888
> > Author: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> > Date:   Wed Nov 9 15:33:17 2016 -0200
> >
> >     [media] gp8psk: Fix DVB frontend attach
> >
> >     it should be calling module_get() at attach, as otherwise
> >     module_put() will crash.
> >
> >     Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> >
> > diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
> > index cede0d8b0f8a..24eb6c6c8e24 100644
> > --- a/drivers/media/usb/dvb-usb/gp8psk.c
> > +++ b/drivers/media/usb/dvb-usb/gp8psk.c
> > @@ -250,7 +250,7 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
> >
> >  static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
> >  {
> > -       adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
> > +       adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, adap->dev);
> >         return 0;
> >  }  
> 
> This gives:
> 
> [119150.498863] DVB: Unable to find symbol gp8psk_fe_attach()
> [119150.498928] dvb-usb: no frontend was attached by 'Genpix
> SkyWalker-2 DVB-S receiver'

Hmm... dvb_attach() assumes that the symbol is exported. Please try
this patch. If it fixes the bug, I'll likely do something else, to
avoid the need of EXPORT_SYMBOL.


[PATCH] [media] gp8psk: Fix DVB frontend attach

it should be calling module_get() at attach, as otherwise
module_put() will crash.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
index db6eb79cde07..ab7c6093436b 100644
--- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c
@@ -326,6 +326,7 @@ struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
 success:
 	return &s->fe;
 }
+EXPORT_SYMBOL_GPL(gp8psk_fe_attach);
 
 
 static struct dvb_frontend_ops gp8psk_fe_ops = {
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 2829e3082d15..c3762c50e93b 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -250,7 +250,7 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 
 static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
+	adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, adap->dev);
 	return 0;
 }
 





Cheers,
Mauro

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-11 12:49                   ` Mauro Carvalho Chehab
@ 2016-11-11 15:33                     ` VDR User
  2016-11-11 21:53                       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 19+ messages in thread
From: VDR User @ 2016-11-11 15:33 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: Mauro Carvalho Chehab, LMML

> Hmm... dvb_attach() assumes that the symbol is exported. Please try
> this patch. If it fixes the bug, I'll likely do something else, to
> avoid the need of EXPORT_SYMBOL.
>
>
> [PATCH] [media] gp8psk: Fix DVB frontend attach
>
> it should be calling module_get() at attach, as otherwise
> module_put() will crash.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
>
> diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
> index db6eb79cde07..ab7c6093436b 100644
> --- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
> +++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c
> @@ -326,6 +326,7 @@ struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
>  success:
>         return &s->fe;
>  }
> +EXPORT_SYMBOL_GPL(gp8psk_fe_attach);
>
>
>  static struct dvb_frontend_ops gp8psk_fe_ops = {
> diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
> index 2829e3082d15..c3762c50e93b 100644
> --- a/drivers/media/usb/dvb-usb/gp8psk.c
> +++ b/drivers/media/usb/dvb-usb/gp8psk.c
> @@ -250,7 +250,7 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
>
>  static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
>  {
> -       adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
> +       adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, adap->dev);
>         return 0;
>  }
>

Unfortunately this still didn't work:

[54856.150095] DVB: registering new adapter (Genpix SkyWalker-2 DVB-S receiver)
[54856.153874] DVB: Unable to find symbol gp8psk_fe_attach()
[54856.153972] dvb-usb: no frontend was attached by 'Genpix
SkyWalker-2 DVB-S receiver'

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-11 15:33                     ` VDR User
@ 2016-11-11 21:53                       ` Mauro Carvalho Chehab
  2016-11-11 22:10                         ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-11 21:53 UTC (permalink / raw)
  To: VDR User; +Cc: Mauro Carvalho Chehab, LMML

Em Fri, 11 Nov 2016 07:33:59 -0800
VDR User <user.vdr@gmail.com> escreveu:

> > Hmm... dvb_attach() assumes that the symbol is exported. Please try
> > this patch. If it fixes the bug, I'll likely do something else, to
> > avoid the need of EXPORT_SYMBOL.
> >
> >
> > [PATCH] [media] gp8psk: Fix DVB frontend attach
> >
> > it should be calling module_get() at attach, as otherwise
> > module_put() will crash.
> >
> > Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> >
> > diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
> > index db6eb79cde07..ab7c6093436b 100644
> > --- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
> > +++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c
> > @@ -326,6 +326,7 @@ struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
> >  success:
> >         return &s->fe;
> >  }
> > +EXPORT_SYMBOL_GPL(gp8psk_fe_attach);
> >
> >
> >  static struct dvb_frontend_ops gp8psk_fe_ops = {
> > diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
> > index 2829e3082d15..c3762c50e93b 100644
> > --- a/drivers/media/usb/dvb-usb/gp8psk.c
> > +++ b/drivers/media/usb/dvb-usb/gp8psk.c
> > @@ -250,7 +250,7 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
> >
> >  static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
> >  {
> > -       adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
> > +       adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, adap->dev);
> >         return 0;
> >  }
> >  
> 
> Unfortunately this still didn't work:
> 
> [54856.150095] DVB: registering new adapter (Genpix SkyWalker-2 DVB-S receiver)
> [54856.153874] DVB: Unable to find symbol gp8psk_fe_attach()
> [54856.153972] dvb-usb: no frontend was attached by 'Genpix
> SkyWalker-2 DVB-S receiver'

I was afraid of that... having the attach symbol at the same
module simply doesn't work. The solution is more complex, as we
need to put the frontend code on a separate driver.

Please test the enclosed patch. It should be doing the right thing.

PS.: There are some other drivers under dvb-usb with the same trouble...
they likely don't handle well device unbind, due to the same reason:

drivers/media/usb/dvb-usb/af9005-fe.c     drivers/media/usb/dvb-usb/friio-fe.c
drivers/media/usb/dvb-usb/cinergyT2-fe.c  drivers/media/usb/dvb-usb/vp702x-fe.c
drivers/media/usb/dvb-usb/dtt200u-fe.c    drivers/media/usb/dvb-usb/vp7045-fe.c

Cheers,
Mauro

[PATCH] [media] gp8psk: Fix DVB frontend attach

The DVB binding schema at the DVB core assumes that the
frontend is a separate driver. Faling to do that causes
OOPS when the module is removed, as it tries to do a
symbol_put_addr on an internal symbol, causing craches like:

 WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70
 Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore nvidia(PO) [last unloaded: rc_core]
 CPU: 1 PID: 28102 Comm: rmmod Tainted: P        WC O 4.8.4-build.1 #1
 Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
 00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6
 c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10
 f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617
 Call Trace:
  [<c12ba080>] ? dump_stack+0x44/0x64
  [<c103ed6a>] ? __warn+0xfa/0x120
  [<c109e8a7>] ? module_put+0x57/0x70
  [<c109e8a7>] ? module_put+0x57/0x70
  [<c103ee33>] ? warn_slowpath_null+0x23/0x30
  [<c109e8a7>] ? module_put+0x57/0x70
  [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk]
  [<c109f617>] ? symbol_put_addr+0x27/0x50
  [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 012225587c25..b71b747ee0ba 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -513,6 +513,11 @@ config DVB_AS102_FE
 	depends on DVB_CORE
 	default DVB_AS102
 
+config DVB_GP8PSK_FE
+	tristate
+	depends on DVB_CORE
+	default DVB_USB_GP8PSK
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index e90165ad361b..93921a4eaa27 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -121,6 +121,7 @@ obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
 obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
 obj-$(CONFIG_DVB_AF9033) += af9033.o
 obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
+obj-$(CONFIG_DVB_GP8PSK_FE) += gp8psk-fe.o
 obj-$(CONFIG_DVB_TC90522) += tc90522.o
 obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
 obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c
similarity index 76%
rename from drivers/media/usb/dvb-usb/gp8psk-fe.c
rename to drivers/media/dvb-frontends/gp8psk-fe.c
index db6eb79cde07..3eb89af7cae9 100644
--- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/dvb-frontends/gp8psk-fe.c
@@ -14,37 +14,45 @@
  *
  * see Documentation/dvb/README.dvb-usb for more information
  */
-#include "gp8psk.h"
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "gp8psk-fe.h"
+
+#include "dvb_frontend.h"
 
 struct gp8psk_fe_state {
 	struct dvb_frontend fe;
-	struct dvb_usb_device *d;
+	bool is_rev1;
 	u8 lock;
 	u16 snr;
 	unsigned long next_status_check;
 	unsigned long status_check_interval;
+
+	const struct gp8psk_fe_ops *ops;
+	void *priv;
 };
 
 static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
 {
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	u8 status;
-	gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
+	st->ops->in(st->priv, GET_8PSK_CONFIG, 0, 0, &status, 1);
 	return status & bmDCtuned;
 }
 
 static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
-	return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+	return st->ops->out(st->priv, SET_8PSK_CONFIG, mode, 0, NULL, 0);
 }
 
 static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
 {
 	u8 buf[6];
 	if (time_after(jiffies,st->next_status_check)) {
-		gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
-		gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
+		st->ops->in(st->priv, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
+		st->ops->in(st->priv, GET_SIGNAL_STRENGTH, 0,0,buf,6);
 		st->snr = (buf[1]) << 8 | buf[0];
 		st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
 	}
@@ -116,13 +124,12 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front
 
 static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	u8 cmd[10];
 	u32 freq = c->frequency * 1000;
-	int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
 
-	deb_fe("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	cmd[4] = freq         & 0xff;
 	cmd[5] = (freq >> 8)  & 0xff;
@@ -136,21 +143,21 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 	switch (c->delivery_system) {
 	case SYS_DVBS:
 		if (c->modulation != QPSK) {
-			deb_fe("%s: unsupported modulation selected (%d)\n",
+			pr_debug("%s: unsupported modulation selected (%d)\n",
 				__func__, c->modulation);
 			return -EOPNOTSUPP;
 		}
 		c->fec_inner = FEC_AUTO;
 		break;
 	case SYS_DVBS2: /* kept for backwards compatibility */
-		deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
+		pr_debug("%s: DVB-S2 delivery system selected\n", __func__);
 		break;
 	case SYS_TURBO:
-		deb_fe("%s: Turbo-FEC delivery system selected\n", __func__);
+		pr_debug("%s: Turbo-FEC delivery system selected\n", __func__);
 		break;
 
 	default:
-		deb_fe("%s: unsupported delivery system selected (%d)\n",
+		pr_debug("%s: unsupported delivery system selected (%d)\n",
 			__func__, c->delivery_system);
 		return -EOPNOTSUPP;
 	}
@@ -161,9 +168,9 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 	cmd[3] = (c->symbol_rate >> 24) & 0xff;
 	switch (c->modulation) {
 	case QPSK:
-		if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+		if (st->is_rev1)
 			if (gp8psk_tuned_to_DCII(fe))
-				gp8psk_bcm4500_reload(state->d);
+				st->ops->reload(st->priv);
 		switch (c->fec_inner) {
 		case FEC_1_2:
 			cmd[9] = 0; break;
@@ -207,18 +214,18 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 		cmd[9] = 0;
 		break;
 	default: /* Unknown modulation */
-		deb_fe("%s: unsupported modulation selected (%d)\n",
+		pr_debug("%s: unsupported modulation selected (%d)\n",
 			__func__, c->modulation);
 		return -EOPNOTSUPP;
 	}
 
-	if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+	if (st->is_rev1)
 		gp8psk_set_tuner_mode(fe, 0);
-	gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
+	st->ops->out(st->priv, TUNE_8PSK, 0, 0, cmd, 10);
 
-	state->lock = 0;
-	state->next_status_check = jiffies;
-	state->status_check_interval = 200;
+	st->lock = 0;
+	st->next_status_check = jiffies;
+	st->status_check_interval = 200;
 
 	return 0;
 }
@@ -228,9 +235,9 @@ static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
 {
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 
-	deb_fe("%s\n",__func__);
+	pr_debug("%s\n",__func__);
 
-	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
+	if (st->ops->out(st->priv,SEND_DISEQC_COMMAND, m->msg[0], 0,
 			m->msg, m->msg_len)) {
 		return -EINVAL;
 	}
@@ -243,12 +250,12 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe,
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	u8 cmd;
 
-	deb_fe("%s\n",__func__);
+	pr_debug("%s\n",__func__);
 
 	/* These commands are certainly wrong */
 	cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
 
-	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
+	if (st->ops->out(st->priv,SEND_DISEQC_COMMAND, cmd, 0,
 			&cmd, 0)) {
 		return -EINVAL;
 	}
@@ -258,9 +265,9 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe,
 static int gp8psk_fe_set_tone(struct dvb_frontend *fe,
 			      enum fe_sec_tone_mode tone)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state* st = fe->demodulator_priv;
 
-	if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
+	if (st->ops->out(st->priv,SET_22KHZ_TONE,
 		 (tone == SEC_TONE_ON), 0, NULL, 0)) {
 		return -EINVAL;
 	}
@@ -270,9 +277,9 @@ static int gp8psk_fe_set_tone(struct dvb_frontend *fe,
 static int gp8psk_fe_set_voltage(struct dvb_frontend *fe,
 				 enum fe_sec_voltage voltage)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state* st = fe->demodulator_priv;
 
-	if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
+	if (st->ops->out(st->priv,SET_LNB_VOLTAGE,
 			 voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
 		return -EINVAL;
 	}
@@ -281,20 +288,20 @@ static int gp8psk_fe_set_voltage(struct dvb_frontend *fe,
 
 static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
-	return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
+	struct gp8psk_fe_state* st = fe->demodulator_priv;
+	return st->ops->out(st->priv, USE_EXTRA_VOLT, onoff, 0,NULL,0);
 }
 
 static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state* st = fe->demodulator_priv;
 	u8 cmd = sw_cmd & 0x7f;
 
-	if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
+	if (st->ops->out(st->priv,SET_DN_SWITCH, cmd, 0,
 			NULL, 0)) {
 		return -EINVAL;
 	}
-	if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
+	if (st->ops->out(st->priv,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
 			0, NULL, 0)) {
 		return -EINVAL;
 	}
@@ -304,29 +311,35 @@ static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned lon
 
 static void gp8psk_fe_release(struct dvb_frontend* fe)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
-	kfree(state);
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+	kfree(st);
 }
 
 static struct dvb_frontend_ops gp8psk_fe_ops;
 
-struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
+struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops,
+				      void *priv, bool is_rev1)
 {
-	struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
-	if (s == NULL)
-		goto error;
-
-	s->d = d;
-	memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
-	s->fe.demodulator_priv = s;
-
-	goto success;
-error:
-	return NULL;
-success:
-	return &s->fe;
-}
+	struct gp8psk_fe_state *st;
+
+	if (!ops || !ops->in || !ops->out || !ops->reload) {
+		pr_err("Error! gp8psk-fe ops not defined.\n");
+		return NULL;
+	}
 
+	st = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
+	if (!st)
+		return NULL;
+
+	memcpy(&st->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
+	st->fe.demodulator_priv = st;
+	st->ops = ops;
+	st->priv = priv;
+	st->is_rev1 = is_rev1;
+
+	return &st->fe;
+}
+EXPORT_SYMBOL_GPL(gp8psk_fe_attach);
 
 static struct dvb_frontend_ops gp8psk_fe_ops = {
 	.delsys = { SYS_DVBS },
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
index 2a7b5a963acf..3b3f32b426d1 100644
--- a/drivers/media/usb/dvb-usb/Makefile
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
 dvb-usb-vp702x-objs := vp702x.o vp702x-fe.o
 obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
 
-dvb-usb-gp8psk-objs := gp8psk.o gp8psk-fe.o
+dvb-usb-gp8psk-objs := gp8psk.o
 obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
 
 dvb-usb-dtt200u-objs := dtt200u.o dtt200u-fe.o
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 2829e3082d15..05d4183806e4 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -15,6 +15,7 @@
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #include "gp8psk.h"
+#include "gp8psk-fe.h"
 
 /* debug */
 static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
@@ -28,34 +29,8 @@ struct gp8psk_state {
 	unsigned char data[80];
 };
 
-static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
-{
-	return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
-}
-
-static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
-{
-	return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
-}
-
-static void gp8psk_info(struct dvb_usb_device *d)
-{
-	u8 fpga_vers, fw_vers[6];
-
-	if (!gp8psk_get_fw_version(d, fw_vers))
-		info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
-		fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
-		2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
-	else
-		info("failed to get FW version");
-
-	if (!gp8psk_get_fpga_version(d, &fpga_vers))
-		info("FPGA Version = %i", fpga_vers);
-	else
-		info("failed to get FPGA version");
-}
-
-int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+static int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
 {
 	struct gp8psk_state *st = d->priv;
 	int ret = 0,try = 0;
@@ -93,7 +68,7 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
 	return ret;
 }
 
-int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+static int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 			     u16 index, u8 *b, int blen)
 {
 	struct gp8psk_state *st = d->priv;
@@ -124,6 +99,34 @@ int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 	return ret;
 }
 
+
+static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
+{
+	return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
+}
+
+static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
+{
+	return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
+}
+
+static void gp8psk_info(struct dvb_usb_device *d)
+{
+	u8 fpga_vers, fw_vers[6];
+
+	if (!gp8psk_get_fw_version(d, fw_vers))
+		info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
+		fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
+		2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
+	else
+		info("failed to get FW version");
+
+	if (!gp8psk_get_fpga_version(d, &fpga_vers))
+		info("FPGA Version = %i", fpga_vers);
+	else
+		info("failed to get FPGA version");
+}
+
 static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
 {
 	int ret;
@@ -226,7 +229,7 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
 	return 0;
 }
 
-int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
+static int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
 {
 	u8 buf;
 	int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
@@ -248,9 +251,46 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 	return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
 }
 
+/* Callbacks for gp8psk-fe.c */
+
+static int gp8psk_fe_in(void *priv, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_usb_in_op(d, req, value, index, b, blen);
+}
+
+static int gp8psk_fe_out(void *priv, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_usb_out_op(d, req, value, index, b, blen);
+}
+
+static int gp8psk_fe_reload(void *priv)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_bcm4500_reload(d);
+}
+
+const struct gp8psk_fe_ops gp8psk_fe_ops = {
+	.in = gp8psk_fe_in,
+	.out = gp8psk_fe_out,
+	.reload = gp8psk_fe_reload,
+};
+
 static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
+	struct dvb_usb_device *d = adap->dev;
+	int id = le16_to_cpu(d->udev->descriptor.idProduct);
+	int is_rev1;
+
+	is_rev1 = (id == USB_PID_GENPIX_8PSK_REV_1_WARM) ? true: false;
+
+	adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, &gp8psk_fe_ops, d, is_rev1);
 	return 0;
 }
 
diff --git a/drivers/media/usb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
index ed32b9da4843..203bc536371f 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.h
+++ b/drivers/media/usb/dvb-usb/gp8psk.h
@@ -26,57 +26,6 @@ extern int dvb_usb_gp8psk_debug;
 #define deb_rc(args...)   dprintk(dvb_usb_gp8psk_debug,0x04,args)
 #define deb_fe(args...)   dprintk(dvb_usb_gp8psk_debug,0x08,args)
 
-/* Twinhan Vendor requests */
-#define TH_COMMAND_IN                     0xC0
-#define TH_COMMAND_OUT                    0xC1
-
-/* gp8psk commands */
-
-#define GET_8PSK_CONFIG                 0x80    /* in */
-#define SET_8PSK_CONFIG                 0x81
-#define I2C_WRITE			0x83
-#define I2C_READ			0x84
-#define ARM_TRANSFER                    0x85
-#define TUNE_8PSK                       0x86
-#define GET_SIGNAL_STRENGTH             0x87    /* in */
-#define LOAD_BCM4500                    0x88
-#define BOOT_8PSK                       0x89    /* in */
-#define START_INTERSIL                  0x8A    /* in */
-#define SET_LNB_VOLTAGE                 0x8B
-#define SET_22KHZ_TONE                  0x8C
-#define SEND_DISEQC_COMMAND             0x8D
-#define SET_DVB_MODE                    0x8E
-#define SET_DN_SWITCH                   0x8F
-#define GET_SIGNAL_LOCK                 0x90    /* in */
-#define GET_FW_VERS			0x92
-#define GET_SERIAL_NUMBER               0x93    /* in */
-#define USE_EXTRA_VOLT                  0x94
-#define GET_FPGA_VERS			0x95
-#define CW3K_INIT			0x9d
-
-/* PSK_configuration bits */
-#define bm8pskStarted                   0x01
-#define bm8pskFW_Loaded                 0x02
-#define bmIntersilOn                    0x04
-#define bmDVBmode                       0x08
-#define bm22kHz                         0x10
-#define bmSEL18V                        0x20
-#define bmDCtuned                       0x40
-#define bmArmed                         0x80
-
-/* Satellite modulation modes */
-#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
-#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
-#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
-#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
-
-#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
-#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
-#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
-#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
-#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
-#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
-
 #define GET_USB_SPEED                     0x07
 
 #define RESET_FX2                         0x13
@@ -86,15 +35,4 @@ extern int dvb_usb_gp8psk_debug;
 #define PRODUCT_STRING_READ               0x0D
 #define FW_BCD_VERSION_READ               0x14
 
-/* firmware revision id's */
-#define GP8PSK_FW_REV1			0x020604
-#define GP8PSK_FW_REV2			0x020704
-#define GP8PSK_FW_VERS(_fw_vers)	((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
-
-extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
-extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
-extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
-			     u16 index, u8 *b, int blen);
-extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
-
 #endif





Cheers,
Mauro

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-11 21:53                       ` Mauro Carvalho Chehab
@ 2016-11-11 22:10                         ` Mauro Carvalho Chehab
  2016-11-12  4:45                           ` VDR User
  0 siblings, 1 reply; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-11 22:10 UTC (permalink / raw)
  To: VDR User; +Cc: LMML

Em Fri, 11 Nov 2016 19:53:53 -0200
Mauro Carvalho Chehab <mchehab@infradead.org> escreveu:

> Em Fri, 11 Nov 2016 07:33:59 -0800
> VDR User <user.vdr@gmail.com> escreveu:
> 
> > > Hmm... dvb_attach() assumes that the symbol is exported. Please try
> > > this patch. If it fixes the bug, I'll likely do something else, to
> > > avoid the need of EXPORT_SYMBOL.
> > >
> > >
> > > [PATCH] [media] gp8psk: Fix DVB frontend attach
> > >
> > > it should be calling module_get() at attach, as otherwise
> > > module_put() will crash.
> > >
> > > Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> > >
> > > diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
> > > index db6eb79cde07..ab7c6093436b 100644
> > > --- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
> > > +++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c
> > > @@ -326,6 +326,7 @@ struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
> > >  success:
> > >         return &s->fe;
> > >  }
> > > +EXPORT_SYMBOL_GPL(gp8psk_fe_attach);
> > >
> > >
> > >  static struct dvb_frontend_ops gp8psk_fe_ops = {
> > > diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
> > > index 2829e3082d15..c3762c50e93b 100644
> > > --- a/drivers/media/usb/dvb-usb/gp8psk.c
> > > +++ b/drivers/media/usb/dvb-usb/gp8psk.c
> > > @@ -250,7 +250,7 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
> > >
> > >  static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
> > >  {
> > > -       adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
> > > +       adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, adap->dev);
> > >         return 0;
> > >  }
> > >    
> > 
> > Unfortunately this still didn't work:
> > 
> > [54856.150095] DVB: registering new adapter (Genpix SkyWalker-2 DVB-S receiver)
> > [54856.153874] DVB: Unable to find symbol gp8psk_fe_attach()
> > [54856.153972] dvb-usb: no frontend was attached by 'Genpix
> > SkyWalker-2 DVB-S receiver'  
> 
> I was afraid of that... having the attach symbol at the same
> module simply doesn't work. The solution is more complex, as we
> need to put the frontend code on a separate driver.
> 
> Please test the enclosed patch. It should be doing the right thing.
> 
> PS.: There are some other drivers under dvb-usb with the same trouble...
> they likely don't handle well device unbind, due to the same reason:
> 
> drivers/media/usb/dvb-usb/af9005-fe.c     drivers/media/usb/dvb-usb/friio-fe.c
> drivers/media/usb/dvb-usb/cinergyT2-fe.c  drivers/media/usb/dvb-usb/vp702x-fe.c
> drivers/media/usb/dvb-usb/dtt200u-fe.c    drivers/media/usb/dvb-usb/vp7045-fe.c
> 
> Cheers,
> Mauro

Sorry, forgot to add one file to the patch.

The right fix is this one.

Regards,
Mauro

[PATCH v2] [media] gp8psk: Fix DVB frontend attach

The DVB binding schema at the DVB core assumes that the
frontend is a separate driver. Faling to do that causes
OOPS when the module is removed, as it tries to do a
symbol_put_addr on an internal symbol, causing craches like:

 WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70
 Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore nvidia(PO) [last unloaded: rc_core]
 CPU: 1 PID: 28102 Comm: rmmod Tainted: P        WC O 4.8.4-build.1 #1
 Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
 00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6
 c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10
 f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617
 Call Trace:
  [<c12ba080>] ? dump_stack+0x44/0x64
  [<c103ed6a>] ? __warn+0xfa/0x120
  [<c109e8a7>] ? module_put+0x57/0x70
  [<c109e8a7>] ? module_put+0x57/0x70
  [<c103ee33>] ? warn_slowpath_null+0x23/0x30
  [<c109e8a7>] ? module_put+0x57/0x70
  [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk]
  [<c109f617>] ? symbol_put_addr+0x27/0x50
  [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 012225587c25..b71b747ee0ba 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -513,6 +513,11 @@ config DVB_AS102_FE
 	depends on DVB_CORE
 	default DVB_AS102
 
+config DVB_GP8PSK_FE
+	tristate
+	depends on DVB_CORE
+	default DVB_USB_GP8PSK
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index e90165ad361b..93921a4eaa27 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -121,6 +121,7 @@ obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
 obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
 obj-$(CONFIG_DVB_AF9033) += af9033.o
 obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
+obj-$(CONFIG_DVB_GP8PSK_FE) += gp8psk-fe.o
 obj-$(CONFIG_DVB_TC90522) += tc90522.o
 obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
 obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c
similarity index 76%
rename from drivers/media/usb/dvb-usb/gp8psk-fe.c
rename to drivers/media/dvb-frontends/gp8psk-fe.c
index db6eb79cde07..3eb89af7cae9 100644
--- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/dvb-frontends/gp8psk-fe.c
@@ -14,37 +14,45 @@
  *
  * see Documentation/dvb/README.dvb-usb for more information
  */
-#include "gp8psk.h"
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "gp8psk-fe.h"
+
+#include "dvb_frontend.h"
 
 struct gp8psk_fe_state {
 	struct dvb_frontend fe;
-	struct dvb_usb_device *d;
+	bool is_rev1;
 	u8 lock;
 	u16 snr;
 	unsigned long next_status_check;
 	unsigned long status_check_interval;
+
+	const struct gp8psk_fe_ops *ops;
+	void *priv;
 };
 
 static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
 {
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	u8 status;
-	gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
+	st->ops->in(st->priv, GET_8PSK_CONFIG, 0, 0, &status, 1);
 	return status & bmDCtuned;
 }
 
 static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
-	return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+	return st->ops->out(st->priv, SET_8PSK_CONFIG, mode, 0, NULL, 0);
 }
 
 static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
 {
 	u8 buf[6];
 	if (time_after(jiffies,st->next_status_check)) {
-		gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
-		gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
+		st->ops->in(st->priv, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
+		st->ops->in(st->priv, GET_SIGNAL_STRENGTH, 0,0,buf,6);
 		st->snr = (buf[1]) << 8 | buf[0];
 		st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
 	}
@@ -116,13 +124,12 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front
 
 static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	u8 cmd[10];
 	u32 freq = c->frequency * 1000;
-	int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
 
-	deb_fe("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	cmd[4] = freq         & 0xff;
 	cmd[5] = (freq >> 8)  & 0xff;
@@ -136,21 +143,21 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 	switch (c->delivery_system) {
 	case SYS_DVBS:
 		if (c->modulation != QPSK) {
-			deb_fe("%s: unsupported modulation selected (%d)\n",
+			pr_debug("%s: unsupported modulation selected (%d)\n",
 				__func__, c->modulation);
 			return -EOPNOTSUPP;
 		}
 		c->fec_inner = FEC_AUTO;
 		break;
 	case SYS_DVBS2: /* kept for backwards compatibility */
-		deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
+		pr_debug("%s: DVB-S2 delivery system selected\n", __func__);
 		break;
 	case SYS_TURBO:
-		deb_fe("%s: Turbo-FEC delivery system selected\n", __func__);
+		pr_debug("%s: Turbo-FEC delivery system selected\n", __func__);
 		break;
 
 	default:
-		deb_fe("%s: unsupported delivery system selected (%d)\n",
+		pr_debug("%s: unsupported delivery system selected (%d)\n",
 			__func__, c->delivery_system);
 		return -EOPNOTSUPP;
 	}
@@ -161,9 +168,9 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 	cmd[3] = (c->symbol_rate >> 24) & 0xff;
 	switch (c->modulation) {
 	case QPSK:
-		if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+		if (st->is_rev1)
 			if (gp8psk_tuned_to_DCII(fe))
-				gp8psk_bcm4500_reload(state->d);
+				st->ops->reload(st->priv);
 		switch (c->fec_inner) {
 		case FEC_1_2:
 			cmd[9] = 0; break;
@@ -207,18 +214,18 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 		cmd[9] = 0;
 		break;
 	default: /* Unknown modulation */
-		deb_fe("%s: unsupported modulation selected (%d)\n",
+		pr_debug("%s: unsupported modulation selected (%d)\n",
 			__func__, c->modulation);
 		return -EOPNOTSUPP;
 	}
 
-	if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+	if (st->is_rev1)
 		gp8psk_set_tuner_mode(fe, 0);
-	gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
+	st->ops->out(st->priv, TUNE_8PSK, 0, 0, cmd, 10);
 
-	state->lock = 0;
-	state->next_status_check = jiffies;
-	state->status_check_interval = 200;
+	st->lock = 0;
+	st->next_status_check = jiffies;
+	st->status_check_interval = 200;
 
 	return 0;
 }
@@ -228,9 +235,9 @@ static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
 {
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 
-	deb_fe("%s\n",__func__);
+	pr_debug("%s\n",__func__);
 
-	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
+	if (st->ops->out(st->priv,SEND_DISEQC_COMMAND, m->msg[0], 0,
 			m->msg, m->msg_len)) {
 		return -EINVAL;
 	}
@@ -243,12 +250,12 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe,
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	u8 cmd;
 
-	deb_fe("%s\n",__func__);
+	pr_debug("%s\n",__func__);
 
 	/* These commands are certainly wrong */
 	cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
 
-	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
+	if (st->ops->out(st->priv,SEND_DISEQC_COMMAND, cmd, 0,
 			&cmd, 0)) {
 		return -EINVAL;
 	}
@@ -258,9 +265,9 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe,
 static int gp8psk_fe_set_tone(struct dvb_frontend *fe,
 			      enum fe_sec_tone_mode tone)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state* st = fe->demodulator_priv;
 
-	if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
+	if (st->ops->out(st->priv,SET_22KHZ_TONE,
 		 (tone == SEC_TONE_ON), 0, NULL, 0)) {
 		return -EINVAL;
 	}
@@ -270,9 +277,9 @@ static int gp8psk_fe_set_tone(struct dvb_frontend *fe,
 static int gp8psk_fe_set_voltage(struct dvb_frontend *fe,
 				 enum fe_sec_voltage voltage)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state* st = fe->demodulator_priv;
 
-	if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
+	if (st->ops->out(st->priv,SET_LNB_VOLTAGE,
 			 voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
 		return -EINVAL;
 	}
@@ -281,20 +288,20 @@ static int gp8psk_fe_set_voltage(struct dvb_frontend *fe,
 
 static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
-	return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
+	struct gp8psk_fe_state* st = fe->demodulator_priv;
+	return st->ops->out(st->priv, USE_EXTRA_VOLT, onoff, 0,NULL,0);
 }
 
 static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state* st = fe->demodulator_priv;
 	u8 cmd = sw_cmd & 0x7f;
 
-	if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
+	if (st->ops->out(st->priv,SET_DN_SWITCH, cmd, 0,
 			NULL, 0)) {
 		return -EINVAL;
 	}
-	if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
+	if (st->ops->out(st->priv,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
 			0, NULL, 0)) {
 		return -EINVAL;
 	}
@@ -304,29 +311,35 @@ static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned lon
 
 static void gp8psk_fe_release(struct dvb_frontend* fe)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
-	kfree(state);
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+	kfree(st);
 }
 
 static struct dvb_frontend_ops gp8psk_fe_ops;
 
-struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
+struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops,
+				      void *priv, bool is_rev1)
 {
-	struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
-	if (s == NULL)
-		goto error;
-
-	s->d = d;
-	memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
-	s->fe.demodulator_priv = s;
-
-	goto success;
-error:
-	return NULL;
-success:
-	return &s->fe;
-}
+	struct gp8psk_fe_state *st;
+
+	if (!ops || !ops->in || !ops->out || !ops->reload) {
+		pr_err("Error! gp8psk-fe ops not defined.\n");
+		return NULL;
+	}
 
+	st = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
+	if (!st)
+		return NULL;
+
+	memcpy(&st->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
+	st->fe.demodulator_priv = st;
+	st->ops = ops;
+	st->priv = priv;
+	st->is_rev1 = is_rev1;
+
+	return &st->fe;
+}
+EXPORT_SYMBOL_GPL(gp8psk_fe_attach);
 
 static struct dvb_frontend_ops gp8psk_fe_ops = {
 	.delsys = { SYS_DVBS },
diff --git a/drivers/media/dvb-frontends/gp8psk-fe.h b/drivers/media/dvb-frontends/gp8psk-fe.h
new file mode 100644
index 000000000000..c83a3575dcac
--- /dev/null
+++ b/drivers/media/dvb-frontends/gp8psk-fe.h
@@ -0,0 +1,80 @@
+/*
+ * gp8psk_fe driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef GP8PSK_FE_H
+#define GP8PSK_FE_H
+
+#include <linux/types.h>
+
+/* gp8psk commands */
+
+#define GET_8PSK_CONFIG                 0x80    /* in */
+#define SET_8PSK_CONFIG                 0x81
+#define I2C_WRITE			0x83
+#define I2C_READ			0x84
+#define ARM_TRANSFER                    0x85
+#define TUNE_8PSK                       0x86
+#define GET_SIGNAL_STRENGTH             0x87    /* in */
+#define LOAD_BCM4500                    0x88
+#define BOOT_8PSK                       0x89    /* in */
+#define START_INTERSIL                  0x8A    /* in */
+#define SET_LNB_VOLTAGE                 0x8B
+#define SET_22KHZ_TONE                  0x8C
+#define SEND_DISEQC_COMMAND             0x8D
+#define SET_DVB_MODE                    0x8E
+#define SET_DN_SWITCH                   0x8F
+#define GET_SIGNAL_LOCK                 0x90    /* in */
+#define GET_FW_VERS			0x92
+#define GET_SERIAL_NUMBER               0x93    /* in */
+#define USE_EXTRA_VOLT                  0x94
+#define GET_FPGA_VERS			0x95
+#define CW3K_INIT			0x9d
+
+/* PSK_configuration bits */
+#define bm8pskStarted                   0x01
+#define bm8pskFW_Loaded                 0x02
+#define bmIntersilOn                    0x04
+#define bmDVBmode                       0x08
+#define bm22kHz                         0x10
+#define bmSEL18V                        0x20
+#define bmDCtuned                       0x40
+#define bmArmed                         0x80
+
+/* Satellite modulation modes */
+#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
+#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
+#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
+#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
+
+#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
+#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
+#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
+#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
+#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
+#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
+
+/* firmware revision id's */
+#define GP8PSK_FW_REV1			0x020604
+#define GP8PSK_FW_REV2			0x020704
+#define GP8PSK_FW_VERS(_fw_vers)	((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
+
+struct gp8psk_fe_ops {
+	int (*in)(void *priv, u8 req, u16 value, u16 index, u8 *b, int blen);
+	int (*out)(void *priv, u8 req, u16 value, u16 index, u8 *b, int blen);
+	int (*reload)(void *priv);
+};
+
+struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops, void *priv, bool is_rev1);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
index 2a7b5a963acf..3b3f32b426d1 100644
--- a/drivers/media/usb/dvb-usb/Makefile
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
 dvb-usb-vp702x-objs := vp702x.o vp702x-fe.o
 obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
 
-dvb-usb-gp8psk-objs := gp8psk.o gp8psk-fe.o
+dvb-usb-gp8psk-objs := gp8psk.o
 obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
 
 dvb-usb-dtt200u-objs := dtt200u.o dtt200u-fe.o
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 2829e3082d15..05d4183806e4 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -15,6 +15,7 @@
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #include "gp8psk.h"
+#include "gp8psk-fe.h"
 
 /* debug */
 static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
@@ -28,34 +29,8 @@ struct gp8psk_state {
 	unsigned char data[80];
 };
 
-static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
-{
-	return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
-}
-
-static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
-{
-	return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
-}
-
-static void gp8psk_info(struct dvb_usb_device *d)
-{
-	u8 fpga_vers, fw_vers[6];
-
-	if (!gp8psk_get_fw_version(d, fw_vers))
-		info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
-		fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
-		2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
-	else
-		info("failed to get FW version");
-
-	if (!gp8psk_get_fpga_version(d, &fpga_vers))
-		info("FPGA Version = %i", fpga_vers);
-	else
-		info("failed to get FPGA version");
-}
-
-int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+static int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
 {
 	struct gp8psk_state *st = d->priv;
 	int ret = 0,try = 0;
@@ -93,7 +68,7 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
 	return ret;
 }
 
-int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+static int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 			     u16 index, u8 *b, int blen)
 {
 	struct gp8psk_state *st = d->priv;
@@ -124,6 +99,34 @@ int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 	return ret;
 }
 
+
+static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
+{
+	return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
+}
+
+static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
+{
+	return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
+}
+
+static void gp8psk_info(struct dvb_usb_device *d)
+{
+	u8 fpga_vers, fw_vers[6];
+
+	if (!gp8psk_get_fw_version(d, fw_vers))
+		info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
+		fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
+		2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
+	else
+		info("failed to get FW version");
+
+	if (!gp8psk_get_fpga_version(d, &fpga_vers))
+		info("FPGA Version = %i", fpga_vers);
+	else
+		info("failed to get FPGA version");
+}
+
 static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
 {
 	int ret;
@@ -226,7 +229,7 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
 	return 0;
 }
 
-int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
+static int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
 {
 	u8 buf;
 	int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
@@ -248,9 +251,46 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 	return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
 }
 
+/* Callbacks for gp8psk-fe.c */
+
+static int gp8psk_fe_in(void *priv, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_usb_in_op(d, req, value, index, b, blen);
+}
+
+static int gp8psk_fe_out(void *priv, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_usb_out_op(d, req, value, index, b, blen);
+}
+
+static int gp8psk_fe_reload(void *priv)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_bcm4500_reload(d);
+}
+
+const struct gp8psk_fe_ops gp8psk_fe_ops = {
+	.in = gp8psk_fe_in,
+	.out = gp8psk_fe_out,
+	.reload = gp8psk_fe_reload,
+};
+
 static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
+	struct dvb_usb_device *d = adap->dev;
+	int id = le16_to_cpu(d->udev->descriptor.idProduct);
+	int is_rev1;
+
+	is_rev1 = (id == USB_PID_GENPIX_8PSK_REV_1_WARM) ? true: false;
+
+	adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, &gp8psk_fe_ops, d, is_rev1);
 	return 0;
 }
 
diff --git a/drivers/media/usb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
index ed32b9da4843..203bc536371f 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.h
+++ b/drivers/media/usb/dvb-usb/gp8psk.h
@@ -26,57 +26,6 @@ extern int dvb_usb_gp8psk_debug;
 #define deb_rc(args...)   dprintk(dvb_usb_gp8psk_debug,0x04,args)
 #define deb_fe(args...)   dprintk(dvb_usb_gp8psk_debug,0x08,args)
 
-/* Twinhan Vendor requests */
-#define TH_COMMAND_IN                     0xC0
-#define TH_COMMAND_OUT                    0xC1
-
-/* gp8psk commands */
-
-#define GET_8PSK_CONFIG                 0x80    /* in */
-#define SET_8PSK_CONFIG                 0x81
-#define I2C_WRITE			0x83
-#define I2C_READ			0x84
-#define ARM_TRANSFER                    0x85
-#define TUNE_8PSK                       0x86
-#define GET_SIGNAL_STRENGTH             0x87    /* in */
-#define LOAD_BCM4500                    0x88
-#define BOOT_8PSK                       0x89    /* in */
-#define START_INTERSIL                  0x8A    /* in */
-#define SET_LNB_VOLTAGE                 0x8B
-#define SET_22KHZ_TONE                  0x8C
-#define SEND_DISEQC_COMMAND             0x8D
-#define SET_DVB_MODE                    0x8E
-#define SET_DN_SWITCH                   0x8F
-#define GET_SIGNAL_LOCK                 0x90    /* in */
-#define GET_FW_VERS			0x92
-#define GET_SERIAL_NUMBER               0x93    /* in */
-#define USE_EXTRA_VOLT                  0x94
-#define GET_FPGA_VERS			0x95
-#define CW3K_INIT			0x9d
-
-/* PSK_configuration bits */
-#define bm8pskStarted                   0x01
-#define bm8pskFW_Loaded                 0x02
-#define bmIntersilOn                    0x04
-#define bmDVBmode                       0x08
-#define bm22kHz                         0x10
-#define bmSEL18V                        0x20
-#define bmDCtuned                       0x40
-#define bmArmed                         0x80
-
-/* Satellite modulation modes */
-#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
-#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
-#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
-#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
-
-#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
-#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
-#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
-#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
-#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
-#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
-
 #define GET_USB_SPEED                     0x07
 
 #define RESET_FX2                         0x13
@@ -86,15 +35,4 @@ extern int dvb_usb_gp8psk_debug;
 #define PRODUCT_STRING_READ               0x0D
 #define FW_BCD_VERSION_READ               0x14
 
-/* firmware revision id's */
-#define GP8PSK_FW_REV1			0x020604
-#define GP8PSK_FW_REV2			0x020704
-#define GP8PSK_FW_VERS(_fw_vers)	((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
-
-extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
-extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
-extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
-			     u16 index, u8 *b, int blen);
-extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
-
 #endif



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-11 22:10                         ` Mauro Carvalho Chehab
@ 2016-11-12  4:45                           ` VDR User
  2016-11-12  4:52                             ` VDR User
  2016-11-12  8:14                             ` Mauro Carvalho Chehab
  0 siblings, 2 replies; 19+ messages in thread
From: VDR User @ 2016-11-12  4:45 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: LMML

> Sorry, forgot to add one file to the patch.
>
> The right fix is this one.

This patch seems to fix the unload crash but unfortunately now all I
get is "frontend 0/0 timed out while tuning".



> [PATCH v2] [media] gp8psk: Fix DVB frontend attach
>
> The DVB binding schema at the DVB core assumes that the
> frontend is a separate driver. Faling to do that causes
> OOPS when the module is removed, as it tries to do a
> symbol_put_addr on an internal symbol, causing craches like:
>
>  WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70
>  Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore nvidia(PO) [last unloaded: rc_core]
>  CPU: 1 PID: 28102 Comm: rmmod Tainted: P        WC O 4.8.4-build.1 #1
>  Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
>  00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6
>  c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10
>  f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617
>  Call Trace:
>   [<c12ba080>] ? dump_stack+0x44/0x64
>   [<c103ed6a>] ? __warn+0xfa/0x120
>   [<c109e8a7>] ? module_put+0x57/0x70
>   [<c109e8a7>] ? module_put+0x57/0x70
>   [<c103ee33>] ? warn_slowpath_null+0x23/0x30
>   [<c109e8a7>] ? module_put+0x57/0x70
>   [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk]
>   [<c109f617>] ? symbol_put_addr+0x27/0x50
>   [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
>
> diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
> index 012225587c25..b71b747ee0ba 100644
> --- a/drivers/media/dvb-frontends/Kconfig
> +++ b/drivers/media/dvb-frontends/Kconfig
> @@ -513,6 +513,11 @@ config DVB_AS102_FE
>         depends on DVB_CORE
>         default DVB_AS102
>
> +config DVB_GP8PSK_FE
> +       tristate
> +       depends on DVB_CORE
> +       default DVB_USB_GP8PSK
> +
>  comment "DVB-C (cable) frontends"
>         depends on DVB_CORE
>
> diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
> index e90165ad361b..93921a4eaa27 100644
> --- a/drivers/media/dvb-frontends/Makefile
> +++ b/drivers/media/dvb-frontends/Makefile
> @@ -121,6 +121,7 @@ obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
>  obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
>  obj-$(CONFIG_DVB_AF9033) += af9033.o
>  obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
> +obj-$(CONFIG_DVB_GP8PSK_FE) += gp8psk-fe.o
>  obj-$(CONFIG_DVB_TC90522) += tc90522.o
>  obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
>  obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
> diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c
> similarity index 76%
> rename from drivers/media/usb/dvb-usb/gp8psk-fe.c
> rename to drivers/media/dvb-frontends/gp8psk-fe.c
> index db6eb79cde07..3eb89af7cae9 100644
> --- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
> +++ b/drivers/media/dvb-frontends/gp8psk-fe.c
> @@ -14,37 +14,45 @@
>   *
>   * see Documentation/dvb/README.dvb-usb for more information
>   */
> -#include "gp8psk.h"
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include "gp8psk-fe.h"
> +
> +#include "dvb_frontend.h"
>
>  struct gp8psk_fe_state {
>         struct dvb_frontend fe;
> -       struct dvb_usb_device *d;
> +       bool is_rev1;
>         u8 lock;
>         u16 snr;
>         unsigned long next_status_check;
>         unsigned long status_check_interval;
> +
> +       const struct gp8psk_fe_ops *ops;
> +       void *priv;
>  };
>
>  static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
>  {
>         struct gp8psk_fe_state *st = fe->demodulator_priv;
>         u8 status;
> -       gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
> +       st->ops->in(st->priv, GET_8PSK_CONFIG, 0, 0, &status, 1);
>         return status & bmDCtuned;
>  }
>
>  static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
>  {
> -       struct gp8psk_fe_state *state = fe->demodulator_priv;
> -       return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
> +       struct gp8psk_fe_state *st = fe->demodulator_priv;
> +       return st->ops->out(st->priv, SET_8PSK_CONFIG, mode, 0, NULL, 0);
>  }
>
>  static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
>  {
>         u8 buf[6];
>         if (time_after(jiffies,st->next_status_check)) {
> -               gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
> -               gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
> +               st->ops->in(st->priv, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
> +               st->ops->in(st->priv, GET_SIGNAL_STRENGTH, 0,0,buf,6);
>                 st->snr = (buf[1]) << 8 | buf[0];
>                 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
>         }
> @@ -116,13 +124,12 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front
>
>  static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
>  {
> -       struct gp8psk_fe_state *state = fe->demodulator_priv;
> +       struct gp8psk_fe_state *st = fe->demodulator_priv;
>         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
>         u8 cmd[10];
>         u32 freq = c->frequency * 1000;
> -       int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
>
> -       deb_fe("%s()\n", __func__);
> +       pr_debug("%s()\n", __func__);
>
>         cmd[4] = freq         & 0xff;
>         cmd[5] = (freq >> 8)  & 0xff;
> @@ -136,21 +143,21 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
>         switch (c->delivery_system) {
>         case SYS_DVBS:
>                 if (c->modulation != QPSK) {
> -                       deb_fe("%s: unsupported modulation selected (%d)\n",
> +                       pr_debug("%s: unsupported modulation selected (%d)\n",
>                                 __func__, c->modulation);
>                         return -EOPNOTSUPP;
>                 }
>                 c->fec_inner = FEC_AUTO;
>                 break;
>         case SYS_DVBS2: /* kept for backwards compatibility */
> -               deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
> +               pr_debug("%s: DVB-S2 delivery system selected\n", __func__);
>                 break;
>         case SYS_TURBO:
> -               deb_fe("%s: Turbo-FEC delivery system selected\n", __func__);
> +               pr_debug("%s: Turbo-FEC delivery system selected\n", __func__);
>                 break;
>
>         default:
> -               deb_fe("%s: unsupported delivery system selected (%d)\n",
> +               pr_debug("%s: unsupported delivery system selected (%d)\n",
>                         __func__, c->delivery_system);
>                 return -EOPNOTSUPP;
>         }
> @@ -161,9 +168,9 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
>         cmd[3] = (c->symbol_rate >> 24) & 0xff;
>         switch (c->modulation) {
>         case QPSK:
> -               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
> +               if (st->is_rev1)
>                         if (gp8psk_tuned_to_DCII(fe))
> -                               gp8psk_bcm4500_reload(state->d);
> +                               st->ops->reload(st->priv);
>                 switch (c->fec_inner) {
>                 case FEC_1_2:
>                         cmd[9] = 0; break;
> @@ -207,18 +214,18 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
>                 cmd[9] = 0;
>                 break;
>         default: /* Unknown modulation */
> -               deb_fe("%s: unsupported modulation selected (%d)\n",
> +               pr_debug("%s: unsupported modulation selected (%d)\n",
>                         __func__, c->modulation);
>                 return -EOPNOTSUPP;
>         }
>
> -       if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
> +       if (st->is_rev1)
>                 gp8psk_set_tuner_mode(fe, 0);
> -       gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
> +       st->ops->out(st->priv, TUNE_8PSK, 0, 0, cmd, 10);
>
> -       state->lock = 0;
> -       state->next_status_check = jiffies;
> -       state->status_check_interval = 200;
> +       st->lock = 0;
> +       st->next_status_check = jiffies;
> +       st->status_check_interval = 200;
>
>         return 0;
>  }
> @@ -228,9 +235,9 @@ static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
>  {
>         struct gp8psk_fe_state *st = fe->demodulator_priv;
>
> -       deb_fe("%s\n",__func__);
> +       pr_debug("%s\n",__func__);
>
> -       if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
> +       if (st->ops->out(st->priv,SEND_DISEQC_COMMAND, m->msg[0], 0,
>                         m->msg, m->msg_len)) {
>                 return -EINVAL;
>         }
> @@ -243,12 +250,12 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe,
>         struct gp8psk_fe_state *st = fe->demodulator_priv;
>         u8 cmd;
>
> -       deb_fe("%s\n",__func__);
> +       pr_debug("%s\n",__func__);
>
>         /* These commands are certainly wrong */
>         cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
>
> -       if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
> +       if (st->ops->out(st->priv,SEND_DISEQC_COMMAND, cmd, 0,
>                         &cmd, 0)) {
>                 return -EINVAL;
>         }
> @@ -258,9 +265,9 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe,
>  static int gp8psk_fe_set_tone(struct dvb_frontend *fe,
>                               enum fe_sec_tone_mode tone)
>  {
> -       struct gp8psk_fe_state* state = fe->demodulator_priv;
> +       struct gp8psk_fe_state* st = fe->demodulator_priv;
>
> -       if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
> +       if (st->ops->out(st->priv,SET_22KHZ_TONE,
>                  (tone == SEC_TONE_ON), 0, NULL, 0)) {
>                 return -EINVAL;
>         }
> @@ -270,9 +277,9 @@ static int gp8psk_fe_set_tone(struct dvb_frontend *fe,
>  static int gp8psk_fe_set_voltage(struct dvb_frontend *fe,
>                                  enum fe_sec_voltage voltage)
>  {
> -       struct gp8psk_fe_state* state = fe->demodulator_priv;
> +       struct gp8psk_fe_state* st = fe->demodulator_priv;
>
> -       if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
> +       if (st->ops->out(st->priv,SET_LNB_VOLTAGE,
>                          voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
>                 return -EINVAL;
>         }
> @@ -281,20 +288,20 @@ static int gp8psk_fe_set_voltage(struct dvb_frontend *fe,
>
>  static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
>  {
> -       struct gp8psk_fe_state* state = fe->demodulator_priv;
> -       return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
> +       struct gp8psk_fe_state* st = fe->demodulator_priv;
> +       return st->ops->out(st->priv, USE_EXTRA_VOLT, onoff, 0,NULL,0);
>  }
>
>  static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
>  {
> -       struct gp8psk_fe_state* state = fe->demodulator_priv;
> +       struct gp8psk_fe_state* st = fe->demodulator_priv;
>         u8 cmd = sw_cmd & 0x7f;
>
> -       if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
> +       if (st->ops->out(st->priv,SET_DN_SWITCH, cmd, 0,
>                         NULL, 0)) {
>                 return -EINVAL;
>         }
> -       if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
> +       if (st->ops->out(st->priv,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
>                         0, NULL, 0)) {
>                 return -EINVAL;
>         }
> @@ -304,29 +311,35 @@ static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned lon
>
>  static void gp8psk_fe_release(struct dvb_frontend* fe)
>  {
> -       struct gp8psk_fe_state *state = fe->demodulator_priv;
> -       kfree(state);
> +       struct gp8psk_fe_state *st = fe->demodulator_priv;
> +       kfree(st);
>  }
>
>  static struct dvb_frontend_ops gp8psk_fe_ops;
>
> -struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
> +struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops,
> +                                     void *priv, bool is_rev1)
>  {
> -       struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
> -       if (s == NULL)
> -               goto error;
> -
> -       s->d = d;
> -       memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
> -       s->fe.demodulator_priv = s;
> -
> -       goto success;
> -error:
> -       return NULL;
> -success:
> -       return &s->fe;
> -}
> +       struct gp8psk_fe_state *st;
> +
> +       if (!ops || !ops->in || !ops->out || !ops->reload) {
> +               pr_err("Error! gp8psk-fe ops not defined.\n");
> +               return NULL;
> +       }
>
> +       st = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
> +       if (!st)
> +               return NULL;
> +
> +       memcpy(&st->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
> +       st->fe.demodulator_priv = st;
> +       st->ops = ops;
> +       st->priv = priv;
> +       st->is_rev1 = is_rev1;
> +
> +       return &st->fe;
> +}
> +EXPORT_SYMBOL_GPL(gp8psk_fe_attach);
>
>  static struct dvb_frontend_ops gp8psk_fe_ops = {
>         .delsys = { SYS_DVBS },
> diff --git a/drivers/media/dvb-frontends/gp8psk-fe.h b/drivers/media/dvb-frontends/gp8psk-fe.h
> new file mode 100644
> index 000000000000..c83a3575dcac
> --- /dev/null
> +++ b/drivers/media/dvb-frontends/gp8psk-fe.h
> @@ -0,0 +1,80 @@
> +/*
> + * gp8psk_fe driver
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2, or (at your option)
> + * any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef GP8PSK_FE_H
> +#define GP8PSK_FE_H
> +
> +#include <linux/types.h>
> +
> +/* gp8psk commands */
> +
> +#define GET_8PSK_CONFIG                 0x80    /* in */
> +#define SET_8PSK_CONFIG                 0x81
> +#define I2C_WRITE                      0x83
> +#define I2C_READ                       0x84
> +#define ARM_TRANSFER                    0x85
> +#define TUNE_8PSK                       0x86
> +#define GET_SIGNAL_STRENGTH             0x87    /* in */
> +#define LOAD_BCM4500                    0x88
> +#define BOOT_8PSK                       0x89    /* in */
> +#define START_INTERSIL                  0x8A    /* in */
> +#define SET_LNB_VOLTAGE                 0x8B
> +#define SET_22KHZ_TONE                  0x8C
> +#define SEND_DISEQC_COMMAND             0x8D
> +#define SET_DVB_MODE                    0x8E
> +#define SET_DN_SWITCH                   0x8F
> +#define GET_SIGNAL_LOCK                 0x90    /* in */
> +#define GET_FW_VERS                    0x92
> +#define GET_SERIAL_NUMBER               0x93    /* in */
> +#define USE_EXTRA_VOLT                  0x94
> +#define GET_FPGA_VERS                  0x95
> +#define CW3K_INIT                      0x9d
> +
> +/* PSK_configuration bits */
> +#define bm8pskStarted                   0x01
> +#define bm8pskFW_Loaded                 0x02
> +#define bmIntersilOn                    0x04
> +#define bmDVBmode                       0x08
> +#define bm22kHz                         0x10
> +#define bmSEL18V                        0x20
> +#define bmDCtuned                       0x40
> +#define bmArmed                         0x80
> +
> +/* Satellite modulation modes */
> +#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
> +#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
> +#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
> +#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
> +
> +#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
> +#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
> +#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
> +#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
> +#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
> +#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
> +
> +/* firmware revision id's */
> +#define GP8PSK_FW_REV1                 0x020604
> +#define GP8PSK_FW_REV2                 0x020704
> +#define GP8PSK_FW_VERS(_fw_vers)       ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
> +
> +struct gp8psk_fe_ops {
> +       int (*in)(void *priv, u8 req, u16 value, u16 index, u8 *b, int blen);
> +       int (*out)(void *priv, u8 req, u16 value, u16 index, u8 *b, int blen);
> +       int (*reload)(void *priv);
> +};
> +
> +struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops, void *priv, bool is_rev1);
> +
> +#endif
> diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
> index 2a7b5a963acf..3b3f32b426d1 100644
> --- a/drivers/media/usb/dvb-usb/Makefile
> +++ b/drivers/media/usb/dvb-usb/Makefile
> @@ -8,7 +8,7 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
>  dvb-usb-vp702x-objs := vp702x.o vp702x-fe.o
>  obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
>
> -dvb-usb-gp8psk-objs := gp8psk.o gp8psk-fe.o
> +dvb-usb-gp8psk-objs := gp8psk.o
>  obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
>
>  dvb-usb-dtt200u-objs := dtt200u.o dtt200u-fe.o
> diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
> index 2829e3082d15..05d4183806e4 100644
> --- a/drivers/media/usb/dvb-usb/gp8psk.c
> +++ b/drivers/media/usb/dvb-usb/gp8psk.c
> @@ -15,6 +15,7 @@
>   * see Documentation/dvb/README.dvb-usb for more information
>   */
>  #include "gp8psk.h"
> +#include "gp8psk-fe.h"
>
>  /* debug */
>  static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
> @@ -28,34 +29,8 @@ struct gp8psk_state {
>         unsigned char data[80];
>  };
>
> -static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
> -{
> -       return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
> -}
> -
> -static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
> -{
> -       return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
> -}
> -
> -static void gp8psk_info(struct dvb_usb_device *d)
> -{
> -       u8 fpga_vers, fw_vers[6];
> -
> -       if (!gp8psk_get_fw_version(d, fw_vers))
> -               info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
> -               fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
> -               2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
> -       else
> -               info("failed to get FW version");
> -
> -       if (!gp8psk_get_fpga_version(d, &fpga_vers))
> -               info("FPGA Version = %i", fpga_vers);
> -       else
> -               info("failed to get FPGA version");
> -}
> -
> -int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
> +static int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
> +                           u16 index, u8 *b, int blen)
>  {
>         struct gp8psk_state *st = d->priv;
>         int ret = 0,try = 0;
> @@ -93,7 +68,7 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
>         return ret;
>  }
>
> -int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
> +static int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
>                              u16 index, u8 *b, int blen)
>  {
>         struct gp8psk_state *st = d->priv;
> @@ -124,6 +99,34 @@ int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
>         return ret;
>  }
>
> +
> +static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
> +{
> +       return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
> +}
> +
> +static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
> +{
> +       return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
> +}
> +
> +static void gp8psk_info(struct dvb_usb_device *d)
> +{
> +       u8 fpga_vers, fw_vers[6];
> +
> +       if (!gp8psk_get_fw_version(d, fw_vers))
> +               info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
> +               fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
> +               2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
> +       else
> +               info("failed to get FW version");
> +
> +       if (!gp8psk_get_fpga_version(d, &fpga_vers))
> +               info("FPGA Version = %i", fpga_vers);
> +       else
> +               info("failed to get FPGA version");
> +}
> +
>  static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
>  {
>         int ret;
> @@ -226,7 +229,7 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
>         return 0;
>  }
>
> -int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
> +static int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
>  {
>         u8 buf;
>         int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
> @@ -248,9 +251,46 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
>         return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
>  }
>
> +/* Callbacks for gp8psk-fe.c */
> +
> +static int gp8psk_fe_in(void *priv, u8 req, u16 value,
> +                           u16 index, u8 *b, int blen)
> +{
> +       struct dvb_usb_device *d = priv;
> +
> +       return gp8psk_usb_in_op(d, req, value, index, b, blen);
> +}
> +
> +static int gp8psk_fe_out(void *priv, u8 req, u16 value,
> +                           u16 index, u8 *b, int blen)
> +{
> +       struct dvb_usb_device *d = priv;
> +
> +       return gp8psk_usb_out_op(d, req, value, index, b, blen);
> +}
> +
> +static int gp8psk_fe_reload(void *priv)
> +{
> +       struct dvb_usb_device *d = priv;
> +
> +       return gp8psk_bcm4500_reload(d);
> +}
> +
> +const struct gp8psk_fe_ops gp8psk_fe_ops = {
> +       .in = gp8psk_fe_in,
> +       .out = gp8psk_fe_out,
> +       .reload = gp8psk_fe_reload,
> +};
> +
>  static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
>  {
> -       adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
> +       struct dvb_usb_device *d = adap->dev;
> +       int id = le16_to_cpu(d->udev->descriptor.idProduct);
> +       int is_rev1;
> +
> +       is_rev1 = (id == USB_PID_GENPIX_8PSK_REV_1_WARM) ? true: false;
> +
> +       adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, &gp8psk_fe_ops, d, is_rev1);
>         return 0;
>  }
>
> diff --git a/drivers/media/usb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
> index ed32b9da4843..203bc536371f 100644
> --- a/drivers/media/usb/dvb-usb/gp8psk.h
> +++ b/drivers/media/usb/dvb-usb/gp8psk.h
> @@ -26,57 +26,6 @@ extern int dvb_usb_gp8psk_debug;
>  #define deb_rc(args...)   dprintk(dvb_usb_gp8psk_debug,0x04,args)
>  #define deb_fe(args...)   dprintk(dvb_usb_gp8psk_debug,0x08,args)
>
> -/* Twinhan Vendor requests */
> -#define TH_COMMAND_IN                     0xC0
> -#define TH_COMMAND_OUT                    0xC1
> -
> -/* gp8psk commands */
> -
> -#define GET_8PSK_CONFIG                 0x80    /* in */
> -#define SET_8PSK_CONFIG                 0x81
> -#define I2C_WRITE                      0x83
> -#define I2C_READ                       0x84
> -#define ARM_TRANSFER                    0x85
> -#define TUNE_8PSK                       0x86
> -#define GET_SIGNAL_STRENGTH             0x87    /* in */
> -#define LOAD_BCM4500                    0x88
> -#define BOOT_8PSK                       0x89    /* in */
> -#define START_INTERSIL                  0x8A    /* in */
> -#define SET_LNB_VOLTAGE                 0x8B
> -#define SET_22KHZ_TONE                  0x8C
> -#define SEND_DISEQC_COMMAND             0x8D
> -#define SET_DVB_MODE                    0x8E
> -#define SET_DN_SWITCH                   0x8F
> -#define GET_SIGNAL_LOCK                 0x90    /* in */
> -#define GET_FW_VERS                    0x92
> -#define GET_SERIAL_NUMBER               0x93    /* in */
> -#define USE_EXTRA_VOLT                  0x94
> -#define GET_FPGA_VERS                  0x95
> -#define CW3K_INIT                      0x9d
> -
> -/* PSK_configuration bits */
> -#define bm8pskStarted                   0x01
> -#define bm8pskFW_Loaded                 0x02
> -#define bmIntersilOn                    0x04
> -#define bmDVBmode                       0x08
> -#define bm22kHz                         0x10
> -#define bmSEL18V                        0x20
> -#define bmDCtuned                       0x40
> -#define bmArmed                         0x80
> -
> -/* Satellite modulation modes */
> -#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
> -#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
> -#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
> -#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
> -
> -#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
> -#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
> -#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
> -#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
> -#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
> -#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
> -
>  #define GET_USB_SPEED                     0x07
>
>  #define RESET_FX2                         0x13
> @@ -86,15 +35,4 @@ extern int dvb_usb_gp8psk_debug;
>  #define PRODUCT_STRING_READ               0x0D
>  #define FW_BCD_VERSION_READ               0x14
>
> -/* firmware revision id's */
> -#define GP8PSK_FW_REV1                 0x020604
> -#define GP8PSK_FW_REV2                 0x020704
> -#define GP8PSK_FW_VERS(_fw_vers)       ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
> -
> -extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
> -extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
> -extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
> -                            u16 index, u8 *b, int blen);
> -extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
> -
>  #endif
>
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-12  4:45                           ` VDR User
@ 2016-11-12  4:52                             ` VDR User
  2016-11-12  5:21                               ` VDR User
  2016-11-12  8:14                             ` Mauro Carvalho Chehab
  1 sibling, 1 reply; 19+ messages in thread
From: VDR User @ 2016-11-12  4:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: LMML

>> Sorry, forgot to add one file to the patch.
>>
>> The right fix is this one.
>
> This patch seems to fix the unload crash but unfortunately now all I
> get is "frontend 0/0 timed out while tuning".

Forgot to mention that I didn't see the gp8psk-fe entry in menuconfig
customize frontends even though the gp8psk module was enabled and set
to <m>. When I exited and saved .config, DVB_GP8PSK_FE was set though.
Maybe something at `config DVB_USB_GP8PSK` in
drivers/media/usb/dvb-usb/Kconfig needs adjusting too?

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-12  4:52                             ` VDR User
@ 2016-11-12  5:21                               ` VDR User
  0 siblings, 0 replies; 19+ messages in thread
From: VDR User @ 2016-11-12  5:21 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: LMML

>>> Sorry, forgot to add one file to the patch.
>>>
>>> The right fix is this one.
>>
>> This patch seems to fix the unload crash but unfortunately now all I
>> get is "frontend 0/0 timed out while tuning".
>
> Forgot to mention that I didn't see the gp8psk-fe entry in menuconfig
> customize frontends even though the gp8psk module was enabled and set
> to <m>. When I exited and saved .config, DVB_GP8PSK_FE was set though.
> Maybe something at `config DVB_USB_GP8PSK` in
> drivers/media/usb/dvb-usb/Kconfig needs adjusting too?

Ugh, forgot to add this as well:

Module                  Size  Used by
gp8psk_fe               3803  1
dvb_usb_gp8psk          7408  4
dvb_usb                17623  1 dvb_usb_gp8psk
dvb_core               74928  1 dvb_usb
lirc_serial             7502  3
lirc_dev                6991  1 lirc_serial
rc_core                16112  2 dvb_usb,lirc_dev

And I noticed something different in dmesg when loading the module.
The prior to the patch it logged:

[   92.041222] dvb-usb: found a 'Genpix SkyWalker-2 DVB-S receiver' in
warm state.
[   93.104244] gp8psk: FW Version = 2.14.6 (0x20e06)  Build 2010/10/10
[   93.104991] gp8psk: FPGA Version = 1
[   93.105367] dvb-usb: will pass the complete MPEG2 transport stream
to the software demuxer.
[   93.105549] DVB: registering new adapter (Genpix SkyWalker-2 DVB-S receiver)
[   93.106614] usb 1-2: DVB: registering adapter 0 frontend 0 (Genpix DVB-S)...
[   93.107620] dvb-usb: Genpix SkyWalker-2 DVB-S receiver successfully
initialized and connected.
[   93.107627] gp8psk: found Genpix USB device pID = 206 (hex)
[   93.107674] usbcore: registered new interface driver dvb_usb_gp8psk

After the patch:

[  542.926237] dvb-usb: found a 'Genpix SkyWalker-2 DVB-S receiver' in
warm state.
[  543.989074] gp8psk: FW Version = 208.00.0 (0xd00000)  Build 2193/15/159
[  543.989945] gp8psk: FPGA Version = 2
[  543.990071] dvb-usb: will pass the complete MPEG2 transport stream
to the software demuxer.
[  543.990257] dvbdev: DVB: registering new adapter (Genpix
SkyWalker-2 DVB-S receiver)
[  543.994589] usb 1-2: DVB: registering adapter 0 frontend 0 (Genpix DVB-S)...
[  543.995575] dvb-usb: Genpix SkyWalker-2 DVB-S receiver successfully
initialized and connected.
[  543.995581] gp8psk: found Genpix USB device pID = 206 (hex)
[  543.995628] usbcore: registered new interface driver dvb_usb_gp8psk

The FW Version and FPGA Version is messed up. Is it possible that
could cause the tuner timeout?

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-12  4:45                           ` VDR User
  2016-11-12  4:52                             ` VDR User
@ 2016-11-12  8:14                             ` Mauro Carvalho Chehab
  2016-11-12 10:20                               ` VDR User
  1 sibling, 1 reply; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-12  8:14 UTC (permalink / raw)
  To: VDR User; +Cc: LMML

Em Fri, 11 Nov 2016 20:45:31 -0800
VDR User <user.vdr@gmail.com> escreveu:

> > Sorry, forgot to add one file to the patch.
> >
> > The right fix is this one.  
> 
> This patch seems to fix the unload crash but unfortunately now all I
> get is "frontend 0/0 timed out while tuning".

I don't see any reason why it should cause any regressions.

> Forgot to mention that I didn't see the gp8psk-fe entry in menuconfig
> customize frontends even though the gp8psk module was enabled and set
> to <m>. When I exited and saved .config, DVB_GP8PSK_FE was set though.
> Maybe something at `config DVB_USB_GP8PSK` in
> drivers/media/usb/dvb-usb/Kconfig needs adjusting too?

I used the same approach taken on as102: the frontend driver is auto-selected
when the gsp8psk driver is selected, and its entry is invisible on normal
make config/gconfig/xconfig, as the drivers can only be used together.

You can still see it at the graphical options if you enable it to show
the hidden symbols.

> And I noticed something different in dmesg when loading the module.
> The prior to the patch it logged:
> 
> [   92.041222] dvb-usb: found a 'Genpix SkyWalker-2 DVB-S receiver' in
> warm state.
> [   93.104244] gp8psk: FW Version = 2.14.6 (0x20e06)  Build 2010/10/10
> [   93.104991] gp8psk: FPGA Version = 1
> [   93.105367] dvb-usb: will pass the complete MPEG2 transport stream
> to the software demuxer.
> [   93.105549] DVB: registering new adapter (Genpix SkyWalker-2 DVB-S receiver)
> [   93.106614] usb 1-2: DVB: registering adapter 0 frontend 0 (Genpix DVB-S)...
> [   93.107620] dvb-usb: Genpix SkyWalker-2 DVB-S receiver successfully
> initialized and connected.
> [   93.107627] gp8psk: found Genpix USB device pID = 206 (hex)
> [   93.107674] usbcore: registered new interface driver dvb_usb_gp8psk
> 
> After the patch:
> 
> [  542.926237] dvb-usb: found a 'Genpix SkyWalker-2 DVB-S receiver' in
> warm state.
> [  543.989074] gp8psk: FW Version = 208.00.0 (0xd00000)  Build 2193/15/159
> [  543.989945] gp8psk: FPGA Version = 2
> [  543.990071] dvb-usb: will pass the complete MPEG2 transport stream
> to the software demuxer.
> [  543.990257] dvbdev: DVB: registering new adapter (Genpix
> SkyWalker-2 DVB-S receiver)
> [  543.994589] usb 1-2: DVB: registering adapter 0 frontend 0 (Genpix DVB-S)...
> [  543.995575] dvb-usb: Genpix SkyWalker-2 DVB-S receiver successfully
> initialized and connected.
> [  543.995581] gp8psk: found Genpix USB device pID = 206 (hex)
> [  543.995628] usbcore: registered new interface driver dvb_usb_gp8psk
> 
> The FW Version and FPGA Version is messed up. Is it possible that
> could cause the tuner timeout?

The version itself is just an information retrieved from the device.
It is not the cause of the trouble. It could be another  symptom, though.
Perhaps some failure happened during device probe, causing the device
to be unstable.

Time to enable the debug messages from the driver and see what changed.

I generated a new version of the patch that should allow enabling all
debug messages from the frontend at once. It also fixes checkpatch
issues.

Please create new file: /etc/modprobe.d/gp8psk.conf with the following 
contents:

	options dvb-usb-gp8psk debug=15
	options gp8psk-fe debug=1

This should allow getting debug messages with and without the patch.
I added a new debug message inside the patch, to indicate if the frontend
driver asks for firmware reload, and another one to indicate that the
firmware driver was properly loaded. Except for that, the other messages
weren't touched.

Could you please apply the patch and pastebin the messages? Please
also pastebin the messages without the patch.

Thanks!
Mauro

[PATCH] [media] gp8psk: Fix DVB frontend attach

The DVB binding schema at the DVB core assumes that the
frontend is a separate driver. Faling to do that causes
OOPS when the module is removed, as it tries to do a
symbol_put_addr on an internal symbol, causing craches like:

 WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70
 Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore nvidia(PO) [last unloaded: rc_core]
 CPU: 1 PID: 28102 Comm: rmmod Tainted: P        WC O 4.8.4-build.1 #1
 Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
 00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6
 c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10
 f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617
 Call Trace:
  [<c12ba080>] ? dump_stack+0x44/0x64
  [<c103ed6a>] ? __warn+0xfa/0x120
  [<c109e8a7>] ? module_put+0x57/0x70
  [<c109e8a7>] ? module_put+0x57/0x70
  [<c103ee33>] ? warn_slowpath_null+0x23/0x30
  [<c109e8a7>] ? module_put+0x57/0x70
  [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk]
  [<c109f617>] ? symbol_put_addr+0x27/0x50
  [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 012225587c25..b71b747ee0ba 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -513,6 +513,11 @@ config DVB_AS102_FE
 	depends on DVB_CORE
 	default DVB_AS102
 
+config DVB_GP8PSK_FE
+	tristate
+	depends on DVB_CORE
+	default DVB_USB_GP8PSK
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index e90165ad361b..93921a4eaa27 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -121,6 +121,7 @@ obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
 obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
 obj-$(CONFIG_DVB_AF9033) += af9033.o
 obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
+obj-$(CONFIG_DVB_GP8PSK_FE) += gp8psk-fe.o
 obj-$(CONFIG_DVB_TC90522) += tc90522.o
 obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
 obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c
similarity index 72%
rename from drivers/media/usb/dvb-usb/gp8psk-fe.c
rename to drivers/media/dvb-frontends/gp8psk-fe.c
index db6eb79cde07..be19afeed7a9 100644
--- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/dvb-frontends/gp8psk-fe.c
@@ -14,11 +14,27 @@
  *
  * see Documentation/dvb/README.dvb-usb for more information
  */
-#include "gp8psk.h"
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "gp8psk-fe.h"
+#include "dvb_frontend.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(fmt, arg...) do {					\
+	if (debug)							\
+		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\
+		       __func__, ##arg);				\
+} while (0)
 
 struct gp8psk_fe_state {
 	struct dvb_frontend fe;
-	struct dvb_usb_device *d;
+	void *priv;
+	const struct gp8psk_fe_ops *ops;
+	bool is_rev1;
 	u8 lock;
 	u16 snr;
 	unsigned long next_status_check;
@@ -29,22 +45,24 @@ static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
 {
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	u8 status;
-	gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
+
+	st->ops->in(st->priv, GET_8PSK_CONFIG, 0, 0, &status, 1);
 	return status & bmDCtuned;
 }
 
 static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
-	return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+
+	return st->ops->out(st->priv, SET_8PSK_CONFIG, mode, 0, NULL, 0);
 }
 
 static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
 {
 	u8 buf[6];
 	if (time_after(jiffies,st->next_status_check)) {
-		gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
-		gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
+		st->ops->in(st->priv, GET_SIGNAL_LOCK, 0, 0, &st->lock, 1);
+		st->ops->in(st->priv, GET_SIGNAL_STRENGTH, 0, 0, buf, 6);
 		st->snr = (buf[1]) << 8 | buf[0];
 		st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
 	}
@@ -116,13 +134,12 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front
 
 static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	u8 cmd[10];
 	u32 freq = c->frequency * 1000;
-	int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
 
-	deb_fe("%s()\n", __func__);
+	dprintk("%s()\n", __func__);
 
 	cmd[4] = freq         & 0xff;
 	cmd[5] = (freq >> 8)  & 0xff;
@@ -136,21 +153,21 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 	switch (c->delivery_system) {
 	case SYS_DVBS:
 		if (c->modulation != QPSK) {
-			deb_fe("%s: unsupported modulation selected (%d)\n",
+			dprintk("%s: unsupported modulation selected (%d)\n",
 				__func__, c->modulation);
 			return -EOPNOTSUPP;
 		}
 		c->fec_inner = FEC_AUTO;
 		break;
 	case SYS_DVBS2: /* kept for backwards compatibility */
-		deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
+		dprintk("%s: DVB-S2 delivery system selected\n", __func__);
 		break;
 	case SYS_TURBO:
-		deb_fe("%s: Turbo-FEC delivery system selected\n", __func__);
+		dprintk("%s: Turbo-FEC delivery system selected\n", __func__);
 		break;
 
 	default:
-		deb_fe("%s: unsupported delivery system selected (%d)\n",
+		dprintk("%s: unsupported delivery system selected (%d)\n",
 			__func__, c->delivery_system);
 		return -EOPNOTSUPP;
 	}
@@ -161,9 +178,9 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 	cmd[3] = (c->symbol_rate >> 24) & 0xff;
 	switch (c->modulation) {
 	case QPSK:
-		if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+		if (st->is_rev1)
 			if (gp8psk_tuned_to_DCII(fe))
-				gp8psk_bcm4500_reload(state->d);
+				st->ops->reload(st->priv);
 		switch (c->fec_inner) {
 		case FEC_1_2:
 			cmd[9] = 0; break;
@@ -207,18 +224,18 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
 		cmd[9] = 0;
 		break;
 	default: /* Unknown modulation */
-		deb_fe("%s: unsupported modulation selected (%d)\n",
+		dprintk("%s: unsupported modulation selected (%d)\n",
 			__func__, c->modulation);
 		return -EOPNOTSUPP;
 	}
 
-	if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+	if (st->is_rev1)
 		gp8psk_set_tuner_mode(fe, 0);
-	gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
+	st->ops->out(st->priv, TUNE_8PSK, 0, 0, cmd, 10);
 
-	state->lock = 0;
-	state->next_status_check = jiffies;
-	state->status_check_interval = 200;
+	st->lock = 0;
+	st->next_status_check = jiffies;
+	st->status_check_interval = 200;
 
 	return 0;
 }
@@ -228,9 +245,9 @@ static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
 {
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 
-	deb_fe("%s\n",__func__);
+	dprintk("%s\n", __func__);
 
-	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
+	if (st->ops->out(st->priv, SEND_DISEQC_COMMAND, m->msg[0], 0,
 			m->msg, m->msg_len)) {
 		return -EINVAL;
 	}
@@ -243,12 +260,12 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe,
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	u8 cmd;
 
-	deb_fe("%s\n",__func__);
+	dprintk("%s\n", __func__);
 
 	/* These commands are certainly wrong */
 	cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
 
-	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
+	if (st->ops->out(st->priv, SEND_DISEQC_COMMAND, cmd, 0,
 			&cmd, 0)) {
 		return -EINVAL;
 	}
@@ -258,10 +275,10 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe,
 static int gp8psk_fe_set_tone(struct dvb_frontend *fe,
 			      enum fe_sec_tone_mode tone)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
 
-	if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
-		 (tone == SEC_TONE_ON), 0, NULL, 0)) {
+	if (st->ops->out(st->priv, SET_22KHZ_TONE,
+			 (tone == SEC_TONE_ON), 0, NULL, 0)) {
 		return -EINVAL;
 	}
 	return 0;
@@ -270,9 +287,9 @@ static int gp8psk_fe_set_tone(struct dvb_frontend *fe,
 static int gp8psk_fe_set_voltage(struct dvb_frontend *fe,
 				 enum fe_sec_voltage voltage)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
 
-	if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
+	if (st->ops->out(st->priv, SET_LNB_VOLTAGE,
 			 voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
 		return -EINVAL;
 	}
@@ -281,52 +298,60 @@ static int gp8psk_fe_set_voltage(struct dvb_frontend *fe,
 
 static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
-	return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+
+	return st->ops->out(st->priv, USE_EXTRA_VOLT, onoff, 0, NULL, 0);
 }
 
 static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
 {
-	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	u8 cmd = sw_cmd & 0x7f;
 
-	if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
-			NULL, 0)) {
+	if (st->ops->out(st->priv, SET_DN_SWITCH, cmd, 0, NULL, 0))
 		return -EINVAL;
-	}
-	if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
-			0, NULL, 0)) {
+
+	if (st->ops->out(st->priv, SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
+			0, NULL, 0))
 		return -EINVAL;
-	}
 
 	return 0;
 }
 
 static void gp8psk_fe_release(struct dvb_frontend* fe)
 {
-	struct gp8psk_fe_state *state = fe->demodulator_priv;
-	kfree(state);
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+
+	kfree(st);
 }
 
 static struct dvb_frontend_ops gp8psk_fe_ops;
 
-struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
+struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops,
+				      void *priv, bool is_rev1)
 {
-	struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
-	if (s == NULL)
-		goto error;
-
-	s->d = d;
-	memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
-	s->fe.demodulator_priv = s;
-
-	goto success;
-error:
-	return NULL;
-success:
-	return &s->fe;
-}
+	struct gp8psk_fe_state *st;
 
+	if (!ops || !ops->in || !ops->out || !ops->reload) {
+		pr_err("Error! gp8psk-fe ops not defined.\n");
+		return NULL;
+	}
+
+	st = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
+	if (!st)
+		return NULL;
+
+	memcpy(&st->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
+	st->fe.demodulator_priv = st;
+	st->ops = ops;
+	st->priv = priv;
+	st->is_rev1 = is_rev1;
+
+	pr_info("Frontend %sattached\n", is_rev1 ? "revision 1 " : "");
+
+	return &st->fe;
+}
+EXPORT_SYMBOL_GPL(gp8psk_fe_attach);
 
 static struct dvb_frontend_ops gp8psk_fe_ops = {
 	.delsys = { SYS_DVBS },
diff --git a/drivers/media/dvb-frontends/gp8psk-fe.h b/drivers/media/dvb-frontends/gp8psk-fe.h
new file mode 100644
index 000000000000..6c7944b1ecd6
--- /dev/null
+++ b/drivers/media/dvb-frontends/gp8psk-fe.h
@@ -0,0 +1,82 @@
+/*
+ * gp8psk_fe driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef GP8PSK_FE_H
+#define GP8PSK_FE_H
+
+#include <linux/types.h>
+
+/* gp8psk commands */
+
+#define GET_8PSK_CONFIG                 0x80    /* in */
+#define SET_8PSK_CONFIG                 0x81
+#define I2C_WRITE			0x83
+#define I2C_READ			0x84
+#define ARM_TRANSFER                    0x85
+#define TUNE_8PSK                       0x86
+#define GET_SIGNAL_STRENGTH             0x87    /* in */
+#define LOAD_BCM4500                    0x88
+#define BOOT_8PSK                       0x89    /* in */
+#define START_INTERSIL                  0x8A    /* in */
+#define SET_LNB_VOLTAGE                 0x8B
+#define SET_22KHZ_TONE                  0x8C
+#define SEND_DISEQC_COMMAND             0x8D
+#define SET_DVB_MODE                    0x8E
+#define SET_DN_SWITCH                   0x8F
+#define GET_SIGNAL_LOCK                 0x90    /* in */
+#define GET_FW_VERS			0x92
+#define GET_SERIAL_NUMBER               0x93    /* in */
+#define USE_EXTRA_VOLT                  0x94
+#define GET_FPGA_VERS			0x95
+#define CW3K_INIT			0x9d
+
+/* PSK_configuration bits */
+#define bm8pskStarted                   0x01
+#define bm8pskFW_Loaded                 0x02
+#define bmIntersilOn                    0x04
+#define bmDVBmode                       0x08
+#define bm22kHz                         0x10
+#define bmSEL18V                        0x20
+#define bmDCtuned                       0x40
+#define bmArmed                         0x80
+
+/* Satellite modulation modes */
+#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
+#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
+#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
+#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
+
+#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
+#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
+#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
+#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
+#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
+#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
+
+/* firmware revision id's */
+#define GP8PSK_FW_REV1			0x020604
+#define GP8PSK_FW_REV2			0x020704
+#define GP8PSK_FW_VERS(_fw_vers) \
+	((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
+
+struct gp8psk_fe_ops {
+	int (*in)(void *priv, u8 req, u16 value, u16 index, u8 *b, int blen);
+	int (*out)(void *priv, u8 req, u16 value, u16 index, u8 *b, int blen);
+	int (*reload)(void *priv);
+};
+
+struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops,
+				      void *priv, bool is_rev1);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
index 2a7b5a963acf..3b3f32b426d1 100644
--- a/drivers/media/usb/dvb-usb/Makefile
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
 dvb-usb-vp702x-objs := vp702x.o vp702x-fe.o
 obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
 
-dvb-usb-gp8psk-objs := gp8psk.o gp8psk-fe.o
+dvb-usb-gp8psk-objs := gp8psk.o
 obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
 
 dvb-usb-dtt200u-objs := dtt200u.o dtt200u-fe.o
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 2829e3082d15..993bb7a72985 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -15,6 +15,7 @@
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #include "gp8psk.h"
+#include "gp8psk-fe.h"
 
 /* debug */
 static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
@@ -28,34 +29,8 @@ struct gp8psk_state {
 	unsigned char data[80];
 };
 
-static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
-{
-	return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
-}
-
-static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
-{
-	return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
-}
-
-static void gp8psk_info(struct dvb_usb_device *d)
-{
-	u8 fpga_vers, fw_vers[6];
-
-	if (!gp8psk_get_fw_version(d, fw_vers))
-		info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
-		fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
-		2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
-	else
-		info("failed to get FW version");
-
-	if (!gp8psk_get_fpga_version(d, &fpga_vers))
-		info("FPGA Version = %i", fpga_vers);
-	else
-		info("failed to get FPGA version");
-}
-
-int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+static int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
 {
 	struct gp8psk_state *st = d->priv;
 	int ret = 0,try = 0;
@@ -93,7 +68,7 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
 	return ret;
 }
 
-int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+static int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 			     u16 index, u8 *b, int blen)
 {
 	struct gp8psk_state *st = d->priv;
@@ -124,6 +99,34 @@ int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 	return ret;
 }
 
+
+static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
+{
+	return gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6);
+}
+
+static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
+{
+	return gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1);
+}
+
+static void gp8psk_info(struct dvb_usb_device *d)
+{
+	u8 fpga_vers, fw_vers[6];
+
+	if (!gp8psk_get_fw_version(d, fw_vers))
+		info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
+		fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
+		2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
+	else
+		info("failed to get FW version");
+
+	if (!gp8psk_get_fpga_version(d, &fpga_vers))
+		info("FPGA Version = %i", fpga_vers);
+	else
+		info("failed to get FPGA version");
+}
+
 static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
 {
 	int ret;
@@ -226,10 +229,13 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
 	return 0;
 }
 
-int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
+static int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
 {
 	u8 buf;
 	int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
+
+	deb_xfer("reloading firmware\n");
+
 	/* Turn off 8psk power */
 	if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
 		return -EINVAL;
@@ -248,9 +254,47 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 	return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
 }
 
+/* Callbacks for gp8psk-fe.c */
+
+static int gp8psk_fe_in(void *priv, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_usb_in_op(d, req, value, index, b, blen);
+}
+
+static int gp8psk_fe_out(void *priv, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_usb_out_op(d, req, value, index, b, blen);
+}
+
+static int gp8psk_fe_reload(void *priv)
+{
+	struct dvb_usb_device *d = priv;
+
+	return gp8psk_bcm4500_reload(d);
+}
+
+const struct gp8psk_fe_ops gp8psk_fe_ops = {
+	.in = gp8psk_fe_in,
+	.out = gp8psk_fe_out,
+	.reload = gp8psk_fe_reload,
+};
+
 static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
+	struct dvb_usb_device *d = adap->dev;
+	int id = le16_to_cpu(d->udev->descriptor.idProduct);
+	int is_rev1;
+
+	is_rev1 = (id == USB_PID_GENPIX_8PSK_REV_1_WARM) ? true : false;
+
+	adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach,
+					 &gp8psk_fe_ops, d, is_rev1);
 	return 0;
 }
 
diff --git a/drivers/media/usb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
index ed32b9da4843..d8975b866dee 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.h
+++ b/drivers/media/usb/dvb-usb/gp8psk.h
@@ -24,58 +24,6 @@ extern int dvb_usb_gp8psk_debug;
 #define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
 #define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
 #define deb_rc(args...)   dprintk(dvb_usb_gp8psk_debug,0x04,args)
-#define deb_fe(args...)   dprintk(dvb_usb_gp8psk_debug,0x08,args)
-
-/* Twinhan Vendor requests */
-#define TH_COMMAND_IN                     0xC0
-#define TH_COMMAND_OUT                    0xC1
-
-/* gp8psk commands */
-
-#define GET_8PSK_CONFIG                 0x80    /* in */
-#define SET_8PSK_CONFIG                 0x81
-#define I2C_WRITE			0x83
-#define I2C_READ			0x84
-#define ARM_TRANSFER                    0x85
-#define TUNE_8PSK                       0x86
-#define GET_SIGNAL_STRENGTH             0x87    /* in */
-#define LOAD_BCM4500                    0x88
-#define BOOT_8PSK                       0x89    /* in */
-#define START_INTERSIL                  0x8A    /* in */
-#define SET_LNB_VOLTAGE                 0x8B
-#define SET_22KHZ_TONE                  0x8C
-#define SEND_DISEQC_COMMAND             0x8D
-#define SET_DVB_MODE                    0x8E
-#define SET_DN_SWITCH                   0x8F
-#define GET_SIGNAL_LOCK                 0x90    /* in */
-#define GET_FW_VERS			0x92
-#define GET_SERIAL_NUMBER               0x93    /* in */
-#define USE_EXTRA_VOLT                  0x94
-#define GET_FPGA_VERS			0x95
-#define CW3K_INIT			0x9d
-
-/* PSK_configuration bits */
-#define bm8pskStarted                   0x01
-#define bm8pskFW_Loaded                 0x02
-#define bmIntersilOn                    0x04
-#define bmDVBmode                       0x08
-#define bm22kHz                         0x10
-#define bmSEL18V                        0x20
-#define bmDCtuned                       0x40
-#define bmArmed                         0x80
-
-/* Satellite modulation modes */
-#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
-#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
-#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
-#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
-
-#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
-#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
-#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
-#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
-#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
-#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
 
 #define GET_USB_SPEED                     0x07
 
@@ -86,15 +34,4 @@ extern int dvb_usb_gp8psk_debug;
 #define PRODUCT_STRING_READ               0x0D
 #define FW_BCD_VERSION_READ               0x14
 
-/* firmware revision id's */
-#define GP8PSK_FW_REV1			0x020604
-#define GP8PSK_FW_REV2			0x020704
-#define GP8PSK_FW_VERS(_fw_vers)	((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
-
-extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
-extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
-extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
-			     u16 index, u8 *b, int blen);
-extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
-
 #endif


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-12  8:14                             ` Mauro Carvalho Chehab
@ 2016-11-12 10:20                               ` VDR User
  2016-11-12 13:59                                 ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 19+ messages in thread
From: VDR User @ 2016-11-12 10:20 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: LMML

Ok, I think I had too much patching going on (I switched from 4.8.4
kernel drivers to media_build) so I started from scratch with a fresh
update to kernel 4.8.7. First I applied the dma stuff in this order:

(from https://patchwork.linuxtv.org/patch/37395/raw/)
v2-18-31-gp8psk-don-t-do-DMA-on-stack.patch
(from https://patchwork.linuxtv.org/patch/37386/raw/)
v2-19-31-gp8psk-don-t-go-past-the-buffer-size.patch
(from https://patchwork.linuxtv.org/patch/37929/raw/)
media-gp8psk-fix-gp8psk_usb_in_op-logic.patch

It works fine at this point but we still have the attach bug. Then I applied:

(from https://patchwork.linuxtv.org/patch/38040/raw/)
Question-about-2-gp8psk-patches-I-noticed-and-possible-bug..patch

Attach bug is fixed, tuning works, module unloads without crashing.
Everything seems ok! I think the gp8psk issues are resolved with the
above 4 patches. As you know, there are some other drivers which
attach the same way as gp8psk was.

Thanks for your help & patience!

One quick question.. Shouldn't gp8psk_fe be listed in the "used by"
column of dvb_usb_gp8psk or the other dvb_* modules?:

Module                  Size  Used by
gp8psk_fe               3803  1
dvb_usb_gp8psk          7344  19
dvb_usb                17495  1 dvb_usb_gp8psk
dvb_core               62327  1 dvb_usb

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Question about 2 gp8psk patches I noticed, and possible bug.
  2016-11-12 10:20                               ` VDR User
@ 2016-11-12 13:59                                 ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2016-11-12 13:59 UTC (permalink / raw)
  To: VDR User; +Cc: LMML

Em Sat, 12 Nov 2016 02:20:37 -0800
VDR User <user.vdr@gmail.com> escreveu:

> Ok, I think I had too much patching going on (I switched from 4.8.4
> kernel drivers to media_build) so I started from scratch with a fresh
> update to kernel 4.8.7. First I applied the dma stuff in this order:
> 
> (from https://patchwork.linuxtv.org/patch/37395/raw/)
> v2-18-31-gp8psk-don-t-do-DMA-on-stack.patch
> (from https://patchwork.linuxtv.org/patch/37386/raw/)
> v2-19-31-gp8psk-don-t-go-past-the-buffer-size.patch
> (from https://patchwork.linuxtv.org/patch/37929/raw/)
> media-gp8psk-fix-gp8psk_usb_in_op-logic.patch
> 
> It works fine at this point but we still have the attach bug. Then I applied:
> 
> (from https://patchwork.linuxtv.org/patch/38040/raw/)
> Question-about-2-gp8psk-patches-I-noticed-and-possible-bug..patch
> 
> Attach bug is fixed, tuning works, module unloads without crashing.
> Everything seems ok! I think the gp8psk issues are resolved with the
> above 4 patches. As you know, there are some other drivers which
> attach the same way as gp8psk was.
> 
> Thanks for your help & patience!

Great!

> 
> One quick question.. Shouldn't gp8psk_fe be listed in the "used by"
> column of dvb_usb_gp8psk or the other dvb_* modules?:
> 
> Module                  Size  Used by
> gp8psk_fe               3803  1

No, the way dvb_attach works don't list what modules use it.
There were a pathset fixing it back in 2008 or something, but
it were never applied upstream.

> dvb_usb_gp8psk          7344  19
> dvb_usb                17495  1 dvb_usb_gp8psk
> dvb_core               62327  1 dvb_usb




Cheers,
Mauro

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2016-11-12 13:59 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAA7C2qjXSkmmCB=zc7Y-Btpwzm_B=_ok0t6qMRuCy+gfrEhcMw@mail.gmail.com>
2016-11-08 17:55 ` Question about 2 gp8psk patches I noticed, and possible bug Mauro Carvalho Chehab
2016-11-09  6:00   ` VDR User
2016-11-09  9:33     ` Mauro Carvalho Chehab
2016-11-09 15:37       ` VDR User
2016-11-09 15:49         ` VDR User
2016-11-09 17:35           ` Mauro Carvalho Chehab
2016-11-10  1:03             ` VDR User
2016-11-10  8:07               ` Mauro Carvalho Chehab
2016-11-10 15:01                 ` VDR User
2016-11-11 12:49                   ` Mauro Carvalho Chehab
2016-11-11 15:33                     ` VDR User
2016-11-11 21:53                       ` Mauro Carvalho Chehab
2016-11-11 22:10                         ` Mauro Carvalho Chehab
2016-11-12  4:45                           ` VDR User
2016-11-12  4:52                             ` VDR User
2016-11-12  5:21                               ` VDR User
2016-11-12  8:14                             ` Mauro Carvalho Chehab
2016-11-12 10:20                               ` VDR User
2016-11-12 13:59                                 ` Mauro Carvalho Chehab

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.