[PATCH] em28xx: Reworked probe code to get rid of some hacks (was: Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick))

2011-12-28 Thread Holger Nelson
Reworked device probing to get rid of hacks to guess the maximum size of 
dvb iso transfer packets. The new code also selects the first alternate 
config which supports the largest possible iso transfers for dvb. 

Signed-off-by: Holger Nelson hnel...@hnelson.de

diff --git a/drivers/media/video/em28xx/em28xx-audio.c 
b/drivers/media/video/em28xx/em28xx-audio.c
index cff0768..e2a7b77 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -193,7 +193,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
 
urb-dev = dev-udev;
urb-context = dev;
-   urb-pipe = usb_rcvisocpipe(dev-udev, 0x83);
+   urb-pipe = usb_rcvisocpipe(dev-udev, EM28XX_EP_AUDIO);
urb-transfer_flags = URB_ISO_ASAP;
urb-transfer_buffer = dev-adev.transfer_buffer[i];
urb-interval = 1;
diff --git a/drivers/media/video/em28xx/em28xx-cards.c 
b/drivers/media/video/em28xx/em28xx-cards.c
index a7cfded..027f769 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -3087,12 +3087,11 @@ unregister_dev:
 static int em28xx_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
 {
-   const struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev;
struct em28xx *dev = NULL;
int retval;
-   bool is_audio_only = false, has_audio = false;
-   int i, nr, isoc_pipe;
+   bool has_audio = false, has_video = false, has_dvb = false;
+   int i, nr;
const int ifnum = interface-altsetting[0].desc.bInterfaceNumber;
char *speed;
char descr[255] = ;
@@ -3124,54 +3123,63 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
goto err;
}
 
+   /* allocate memory for our device state and initialize it */
+   dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+   if (dev == NULL) {
+   em28xx_err(DRIVER_NAME : out of memory!\n);
+   retval = -ENOMEM;
+   goto err;
+   }
+
+   /* compute alternate max packet sizes */
+   dev-alt_max_pkt_size = kmalloc(sizeof(dev-alt_max_pkt_size[0]) * 
interface-num_altsetting, GFP_KERNEL);
+   if (dev-alt_max_pkt_size == NULL) {
+   em28xx_errdev(out of memory!\n);
+   kfree(dev);
+   retval = -ENOMEM;
+   goto err;
+   }
+
/* Get endpoints */
for (i = 0; i  interface-num_altsetting; i++) {
int ep;
 
for (ep = 0; ep  interface-altsetting[i].desc.bNumEndpoints; 
ep++) {
-   struct usb_host_endpoint*e;
-   e = interface-altsetting[i].endpoint[ep];
-
-   if (e-desc.bEndpointAddress == 0x83)
-   has_audio = true;
+   const struct usb_endpoint_descriptor *e;
+   int sizedescr, size;
+
+   e = interface-altsetting[i].endpoint[ep].desc;
+
+   sizedescr = le16_to_cpu(e-wMaxPacketSize);
+   size = sizedescr  0x7ff;
+
+   if (udev-speed == USB_SPEED_HIGH)
+   size = size * hb_mult(sizedescr);
+
+   if (usb_endpoint_xfer_isoc(e)  
usb_endpoint_dir_in(e)) {
+   switch (e-bEndpointAddress) {
+   case EM28XX_EP_AUDIO:
+   has_audio = true;
+   break;
+   case EM28XX_EP_ANALOG:
+   has_video = true;
+   dev-alt_max_pkt_size[i] = size;
+   break;
+   case EM28XX_EP_DIGITAL:
+   has_dvb = true;
+   if (size  dev-dvb_max_pkt_size) {
+   dev-dvb_max_pkt_size = size;
+   dev-dvb_alt = i;
+   }
+   break;
+   }
+   }
}
}
 
-   endpoint = interface-cur_altsetting-endpoint[0].desc;
-
-   /* check if the device has the iso in endpoint at the correct place */
-   if (usb_endpoint_xfer_isoc(endpoint)
-   
-   (interface-altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) {
-   /* It's a newer em2874/em2875 device */
-   isoc_pipe = 0;
-   } else {
-   int check_interface = 1;
-   isoc_pipe = 1;
-   endpoint = interface-cur_altsetting-endpoint[1].desc;
-   if (!usb_endpoint_xfer_isoc(endpoint))
- 

Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-27 Thread Holger Nelson

On Mon, 26 Dec 2011, Mauro Carvalho Chehab wrote:


I'm currently without time right now to work on a patch, but I think that 
several hacks
inside the em28xx probe should be removed, including the one that detects the 
endpoint
based on the packet size.

As it is easier to code than to explain in words, the code below could be
a start (ok, it doesn't compile, doesn't remove all hacks, doesn't free memory, 
etc...)
Feel free to use it as a start for a real patch, if you wish.


I think, I filled the missing parts and removed most of the hacks in the 
probe code. The code works with my Cinergy HTC USB XS.


Holger

diff --git a/drivers/media/video/em28xx/em28xx-audio.c 
b/drivers/media/video/em28xx/em28xx-audio.c
index cff0768..e2a7b77 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -193,7 +193,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)

urb-dev = dev-udev;
urb-context = dev;
-   urb-pipe = usb_rcvisocpipe(dev-udev, 0x83);
+   urb-pipe = usb_rcvisocpipe(dev-udev, EM28XX_EP_AUDIO);
urb-transfer_flags = URB_ISO_ASAP;
urb-transfer_buffer = dev-adev.transfer_buffer[i];
urb-interval = 1;
diff --git a/drivers/media/video/em28xx/em28xx-cards.c 
b/drivers/media/video/em28xx/em28xx-cards.c
index a7cfded..8082914 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -3087,12 +3087,11 @@ unregister_dev:
 static int em28xx_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
 {
-   const struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev;
struct em28xx *dev = NULL;
int retval;
-   bool is_audio_only = false, has_audio = false;
-   int i, nr, isoc_pipe;
+   bool has_audio = false, has_video = false, has_dvb = false;
+   int i, nr, sizedescr, size;
const int ifnum = interface-altsetting[0].desc.bInterfaceNumber;
char *speed;
char descr[255] = ;
@@ -3124,56 +3123,69 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
goto err;
}

-   /* Get endpoints */
-   for (i = 0; i  interface-num_altsetting; i++) {
-   int ep;
+   /* allocate memory for our device state and initialize it */
+   dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+   if (dev == NULL) {
+   em28xx_err(DRIVER_NAME : out of memory!\n);
+   retval = -ENOMEM;
+   goto err;
+   }

-   for (ep = 0; ep  interface-altsetting[i].desc.bNumEndpoints; 
ep++) {
-   struct usb_host_endpoint*e;
-   e = interface-altsetting[i].endpoint[ep];
+   /* compute alternate max packet sizes */
+   dev-alt_video_max_pkt_size = 
kmalloc(sizeof(dev-alt_video_max_pkt_size[0]) * interface-num_altsetting, 
GFP_KERNEL);
+   if (dev-alt_video_max_pkt_size == NULL) {
+   em28xx_errdev(out of memory!\n);
+   kfree(dev);
+   retval = -ENOMEM;
+   goto err;
+   }

-   if (e-desc.bEndpointAddress == 0x83)
-   has_audio = true;
-   }
+   dev-alt_dvb_max_pkt_size = kmalloc(sizeof(dev-alt_dvb_max_pkt_size[0]) * 
interface-num_altsetting, GFP_KERNEL);
+   if (dev-alt_dvb_max_pkt_size == NULL) {
+   em28xx_errdev(out of memory!\n);
+   kfree(dev-alt_video_max_pkt_size);
+   kfree(dev);
+   retval = -ENOMEM;
+   goto err;
}

-   endpoint = interface-cur_altsetting-endpoint[0].desc;
+   /* Get endpoints */
+   for (i = 0; i  interface-num_altsetting; i++) {
+   int ep;

-   /* check if the device has the iso in endpoint at the correct place */
-   if (usb_endpoint_xfer_isoc(endpoint)
-   
-   (interface-altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) {
-   /* It's a newer em2874/em2875 device */
-   isoc_pipe = 0;
-   } else {
-   int check_interface = 1;
-   isoc_pipe = 1;
-   endpoint = interface-cur_altsetting-endpoint[1].desc;
-   if (!usb_endpoint_xfer_isoc(endpoint))
-   check_interface = 0;
-
-   if (usb_endpoint_dir_out(endpoint))
-   check_interface = 0;
-
-   if (!check_interface) {
-   if (has_audio) {
-   is_audio_only = true;
-   } else {
-   em28xx_err(DRIVER_NAME  video device (%04x:%04x): 

-   interface %i, class %i found.\n,
-   le16_to_cpu(udev-descriptor.idVendor),
-   

Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Dennis Sperlich

On 25.12.2011 11:52, Mauro Carvalho Chehab wrote:

On 24-12-2011 19:58, Dennis Sperlich wrote:

Hi,

I have a Terratec Cinergy HTC Stick an tried the new support for the DVB-C 
part. It works for SD material (at least for free receivable stations, I tried 
afair only QAM64), but did not for HD stations (QAM256). I have only access to 
unencrypted ARD HD, ZDF HD and arte HD (via KabelDeutschland). The HD material 
was just digital artefacts, as far as mplayer could decode it. When I did a 
dumpstream and looked at the resulting file size I got something about 1MB/s 
which seems a little too low, because SD was already about 870kB/s. After 
looking around I found a solution in increasing the isoc_dvb_max_packetsize 
from 752 to 940 (multiple of 188). Then an HD stream was about 1.4MB/s and 
looked good. I'm not sure, whether this is the correct fix, but it works for me.

If you need more testing pleas tell.

Regards,
Dennis



index 804a4ab..c518d13 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1157,7 +1157,7 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
  * FIXME: same as em2874. 564 was enough for 22 Mbit DVB-T
  * but not enough for 44 Mbit DVB-C.
  */
-   packet_size = 752;
+   packet_size = 940;
 }

 return packet_size;

As you can see there at the code, the packet size depends on the chipset, as
not all will support 940 for packet size.

Could you please provide us what was the chip detected id?

It should be a message on your dmesg like:

chip ID is em2870
or
em28xx chip ID = 38

The patch should change it only for your specific chipset model, in order to
avoid regressions to other supported chipsets, like:

int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
{
 unsigned int chip_cfg2;
 unsigned int packet_size;

 switch (dev-chip_id) {
 case CHIP_ID_EM2710:
 case CHIP_ID_EM2750:
 case CHIP_ID_EM2800:
 case CHIP_ID_EM2820:
...
case CHIP_ID_foo:
packet_size = 940;
...
 }

 return packet_size;
}

The case you're touching seems to be for em2884, but the switch covers both
em2884 and em28174 (plus the default for newer chipsets).


dmesg says: em28xx #0: chip ID is em2884

so a patch would be more like:

index 804a4ab..9280251 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1151,6 +1151,8 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
packet_size = 564;
break;
case CHIP_ID_EM2884:
+   packet_size = 940;
+   break;
case CHIP_ID_EM28174:
default:
/*


Maybe Michael/Devin may have something to say, with regards to a way to detect
the maximum supported packet size by each specific em28xx model.


This would be fine, I tried also 1128 (6 times 188), but then mplayer 
did not play any more. I then tried 1034, but then I got the message  
submit of urb 0 failed (error=-90), so I guess there have to be integer 
multiples of 188.


Regards,
Dennis
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Hans Petter Selasky
On Sunday 25 December 2011 15:04:17 Dennis Sperlich wrote:
 On 25.12.2011 11:52, Mauro Carvalho Chehab wrote:
  On 24-12-2011 19:58, Dennis Sperlich wrote:
  Hi,
  
  I have a Terratec Cinergy HTC Stick an tried the new support for the
  DVB-C part. It works for SD material (at least for free receivable
  stations, I tried afair only QAM64), but did not for HD stations
  (QAM256). I have only access to unencrypted ARD HD, ZDF HD and arte HD
  (via KabelDeutschland). The HD material was just digital artefacts, as
  far as mplayer could decode it. When I did a dumpstream and looked at
  the resulting file size I got something about 1MB/s which seems a
  little too low, because SD was already about 870kB/s. After looking
  around I found a solution in increasing the isoc_dvb_max_packetsize
  from 752 to 940 (multiple of 188). Then an HD stream was about 1.4MB/s
  and looked good. I'm not sure, whether this is the correct fix, but it
  works for me.
  
  If you need more testing pleas tell.
  
  Regards,
  Dennis
  

These numbers should not be hardcoded, but extracted from the USB endpoint 
descriptor!

--HPS
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Devin Heitmueller
On Sun, Dec 25, 2011 at 9:11 AM, Hans Petter Selasky hsela...@c2i.net wrote:
 These numbers should not be hardcoded, but extracted from the USB endpoint
 descriptor!

 --HPS

Hans is correct.  I only hard-coded it at 564 as a quick hack when I
was bootstrapping the em2784 support.  The code really should be
cleaned up to base it off of the endpoint descriptors.

Patches certainly welcome as this is indeed a known issue.

Devin

-- 
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Mauro Carvalho Chehab
On 25-12-2011 12:11, Hans Petter Selasky wrote:
 On Sunday 25 December 2011 15:04:17 Dennis Sperlich wrote:
 On 25.12.2011 11:52, Mauro Carvalho Chehab wrote:
 On 24-12-2011 19:58, Dennis Sperlich wrote:
 Hi,

 I have a Terratec Cinergy HTC Stick an tried the new support for the
 DVB-C part. It works for SD material (at least for free receivable
 stations, I tried afair only QAM64), but did not for HD stations
 (QAM256). I have only access to unencrypted ARD HD, ZDF HD and arte HD
 (via KabelDeutschland). The HD material was just digital artefacts, as
 far as mplayer could decode it. When I did a dumpstream and looked at
 the resulting file size I got something about 1MB/s which seems a
 little too low, because SD was already about 870kB/s. After looking
 around I found a solution in increasing the isoc_dvb_max_packetsize
 from 752 to 940 (multiple of 188). Then an HD stream was about 1.4MB/s
 and looked good. I'm not sure, whether this is the correct fix, but it
 works for me.

 If you need more testing pleas tell.

 Regards,
 Dennis

 
 These numbers should not be hardcoded, but extracted from the USB endpoint 
 descriptor!

The driver retrieves the values from the USB endpoints during probe. This
is used for analog mode. However, on DVB mode, the values are hardcoded by
the ones that had/have access to Empiatech datasheets (Unfortunately,
I don't have them).

So, it is hard to know if the current limit is due to some chipset bug that
doesn't report well the maximum packet size, or if it is just due to the lack
of time for the ones that wrote the code to actually use the reported values.

Fixing the driver to use the USB descriptors is easy. The hard part is to be
sure that it won't break for the ones with older chipsets.

Regards,
Mauro.

 
 --HPS

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Mauro Carvalho Chehab
On 25-12-2011 12:04, Dennis Sperlich wrote:
 On 25.12.2011 11:52, Mauro Carvalho Chehab wrote:
 On 24-12-2011 19:58, Dennis Sperlich wrote:
 Hi,

 I have a Terratec Cinergy HTC Stick an tried the new support for the DVB-C 
 part. It works for SD material (at least for free receivable stations, I 
 tried afair only QAM64), but did not for HD stations (QAM256). I have only 
 access to unencrypted ARD HD, ZDF HD and arte HD (via KabelDeutschland). 
 The HD material was just digital artefacts, as far as mplayer could decode 
 it. When I did a dumpstream and looked at the resulting file size I got 
 something about 1MB/s which seems a little too low, because SD was already 
 about 870kB/s. After looking around I found a solution in increasing the 
 isoc_dvb_max_packetsize from 752 to 940 (multiple of 188). Then an HD 
 stream was about 1.4MB/s and looked good. I'm not sure, whether this is the 
 correct fix, but it works for me.

 If you need more testing pleas tell.

 Regards,
 Dennis



 index 804a4ab..c518d13 100644
 --- a/drivers/media/video/em28xx/em28xx-core.c
 +++ b/drivers/media/video/em28xx/em28xx-core.c
 @@ -1157,7 +1157,7 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
   * FIXME: same as em2874. 564 was enough for 22 Mbit DVB-T
   * but not enough for 44 Mbit DVB-C.
   */
 -   packet_size = 752;
 +   packet_size = 940;
  }

  return packet_size;
 As you can see there at the code, the packet size depends on the chipset, as
 not all will support 940 for packet size.

 Could you please provide us what was the chip detected id?

 It should be a message on your dmesg like:

 chip ID is em2870
 or
 em28xx chip ID = 38

 The patch should change it only for your specific chipset model, in order to
 avoid regressions to other supported chipsets, like:

 int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
 {
  unsigned int chip_cfg2;
  unsigned int packet_size;

  switch (dev-chip_id) {
  case CHIP_ID_EM2710:
  case CHIP_ID_EM2750:
  case CHIP_ID_EM2800:
  case CHIP_ID_EM2820:
 ...
 case CHIP_ID_foo:
 packet_size = 940;
 ...
  }

  return packet_size;
 }

 The case you're touching seems to be for em2884, but the switch covers both
 em2884 and em28174 (plus the default for newer chipsets).
 
 dmesg says: em28xx #0: chip ID is em2884
 
 so a patch would be more like:
 
 index 804a4ab..9280251 100644
 --- a/drivers/media/video/em28xx/em28xx-core.c
 +++ b/drivers/media/video/em28xx/em28xx-core.c
 @@ -1151,6 +1151,8 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
 packet_size = 564;
 break;
 case CHIP_ID_EM2884:
 +   packet_size = 940;
 +   break;
 case CHIP_ID_EM28174:
 default:
 /*
 
 Maybe Michael/Devin may have something to say, with regards to a way to 
 detect
 the maximum supported packet size by each specific em28xx model.
 
 This would be fine, I tried also 1128 (6 times 188), but then mplayer did not 
 play any more.
 I then tried 1034, but then I got the message  submit of urb 0 failed 
 (error=-90), so I guess 
 there have to be integer multiples of 188.

The maximum packet size is described at the USB descriptors.

The code at em28xx_set_alternate() seeks for the alternates and selects
the one that will get the best alternate for the analog mode.

There, you'll see a code that gets the best alternate for analog,
and selects the proper packet size for it.

For DVB, it should be a little different, as, on DVB, the driver doesn't
know, in advance, what's the streaming rate. So, the driver needs to get
a high enough packet size to fit for the bandwidth needs.

Also, for DVB, the driver does:
usb_set_interface(dev-udev, 0, 1);

(e. g. it always use alternate 1)

So, in thesis, that function could be as simple as:
dev-alt_max_pkt_size[1];

(if the max packet size for alternate 1 would work for all chips)

Or, eventually, the code might be using other alternates for HD, 
but I'm not sure if those chipsets support a different alternate for DVB.

Regards,
Mauro
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Malcolm Priestley
On Sun, 2011-12-25 at 15:11 +0100, Hans Petter Selasky wrote:
 On Sunday 25 December 2011 15:04:17 Dennis Sperlich wrote:
  On 25.12.2011 11:52, Mauro Carvalho Chehab wrote:
   On 24-12-2011 19:58, Dennis Sperlich wrote:
   Hi,
   
   I have a Terratec Cinergy HTC Stick an tried the new support for the
   DVB-C part. It works for SD material (at least for free receivable
   stations, I tried afair only QAM64), but did not for HD stations
   (QAM256). I have only access to unencrypted ARD HD, ZDF HD and arte HD
   (via KabelDeutschland). The HD material was just digital artefacts, as
   far as mplayer could decode it. When I did a dumpstream and looked at
   the resulting file size I got something about 1MB/s which seems a
   little too low, because SD was already about 870kB/s. After looking
   around I found a solution in increasing the isoc_dvb_max_packetsize
   from 752 to 940 (multiple of 188). Then an HD stream was about 1.4MB/s
   and looked good. I'm not sure, whether this is the correct fix, but it
   works for me.
   

Would not increasing EM28XX_DVB_NUM_BUFS currently set at 5 to say 10
have a better effect?

Malcolm

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Dennis Sperlich

On 25.12.2011 20:42, Malcolm Priestley wrote:

On Sun, 2011-12-25 at 15:11 +0100, Hans Petter Selasky wrote:

On Sunday 25 December 2011 15:04:17 Dennis Sperlich wrote:

On 25.12.2011 11:52, Mauro Carvalho Chehab wrote:

On 24-12-2011 19:58, Dennis Sperlich wrote:

Hi,

I have a Terratec Cinergy HTC Stick an tried the new support for the
DVB-C part. It works for SD material (at least for free receivable
stations, I tried afair only QAM64), but did not for HD stations
(QAM256). I have only access to unencrypted ARD HD, ZDF HD and arte HD
(via KabelDeutschland). The HD material was just digital artefacts, as
far as mplayer could decode it. When I did a dumpstream and looked at
the resulting file size I got something about 1MB/s which seems a
little too low, because SD was already about 870kB/s. After looking
around I found a solution in increasing the isoc_dvb_max_packetsize
from 752 to 940 (multiple of 188). Then an HD stream was about 1.4MB/s
and looked good. I'm not sure, whether this is the correct fix, but it
works for me.


Would not increasing EM28XX_DVB_NUM_BUFS currently set at 5 to say 10
have a better effect?

This does not work, I just tried it.

Regards,
Dennis
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Dennis Sperlich

On 25.12.2011 19:13, Mauro Carvalho Chehab wrote:

On 25-12-2011 12:04, Dennis Sperlich wrote:

On 25.12.2011 11:52, Mauro Carvalho Chehab wrote:

On 24-12-2011 19:58, Dennis Sperlich wrote:

Hi,

I have a Terratec Cinergy HTC Stick an tried the new support for the DVB-C 
part. It works for SD material (at least for free receivable stations, I tried 
afair only QAM64), but did not for HD stations (QAM256). I have only access to 
unencrypted ARD HD, ZDF HD and arte HD (via KabelDeutschland). The HD material 
was just digital artefacts, as far as mplayer could decode it. When I did a 
dumpstream and looked at the resulting file size I got something about 1MB/s 
which seems a little too low, because SD was already about 870kB/s. After 
looking around I found a solution in increasing the isoc_dvb_max_packetsize 
from 752 to 940 (multiple of 188). Then an HD stream was about 1.4MB/s and 
looked good. I'm not sure, whether this is the correct fix, but it works for me.

If you need more testing pleas tell.

Regards,
Dennis



index 804a4ab..c518d13 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1157,7 +1157,7 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
   * FIXME: same as em2874. 564 was enough for 22 Mbit DVB-T
   * but not enough for 44 Mbit DVB-C.
   */
-   packet_size = 752;
+   packet_size = 940;
  }

  return packet_size;

As you can see there at the code, the packet size depends on the chipset, as
not all will support 940 for packet size.

Could you please provide us what was the chip detected id?

It should be a message on your dmesg like:

 chip ID is em2870
or
 em28xx chip ID = 38

The patch should change it only for your specific chipset model, in order to
avoid regressions to other supported chipsets, like:

int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
{
  unsigned int chip_cfg2;
  unsigned int packet_size;

  switch (dev-chip_id) {
  case CHIP_ID_EM2710:
  case CHIP_ID_EM2750:
  case CHIP_ID_EM2800:
  case CHIP_ID_EM2820:
...
 case CHIP_ID_foo:
 packet_size = 940;
...
  }

  return packet_size;
}

The case you're touching seems to be for em2884, but the switch covers both
em2884 and em28174 (plus the default for newer chipsets).

dmesg says: em28xx #0: chip ID is em2884

so a patch would be more like:

index 804a4ab..9280251 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1151,6 +1151,8 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
 packet_size = 564;
 break;
 case CHIP_ID_EM2884:
+   packet_size = 940;
+   break;
 case CHIP_ID_EM28174:
 default:
 /*


Maybe Michael/Devin may have something to say, with regards to a way to detect
the maximum supported packet size by each specific em28xx model.

This would be fine, I tried also 1128 (6 times 188), but then mplayer did not 
play any more.
I then tried 1034, but then I got the message  submit of urb 0 failed 
(error=-90), so I guess
there have to be integer multiples of 188.

The maximum packet size is described at the USB descriptors.

The code at em28xx_set_alternate() seeks for the alternates and selects
the one that will get the best alternate for the analog mode.

There, you'll see a code that gets the best alternate for analog,
and selects the proper packet size for it.

For DVB, it should be a little different, as, on DVB, the driver doesn't
know, in advance, what's the streaming rate. So, the driver needs to get
a high enough packet size to fit for the bandwidth needs.

Also, for DVB, the driver does:
usb_set_interface(dev-udev, 0, 1);

(e. g. it always use alternate 1)

So, in thesis, that function could be as simple as:
dev-alt_max_pkt_size[1];

(if the max packet size for alternate 1 would work for all chips)

Or, eventually, the code might be using other alternates for HD,
but I'm not sure if those chipsets support a different alternate for DVB.

I just tried, replacing
max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev);
by
max_dvb_packet_size = dev-alt_max_pkt_size[1];

but it did not work. Was this the correct replacement?

printk(KERN_INFO dev-alt_max_pkt_size[1] is 
%i\n,dev-alt_max_pkt_size[1]);


then said, dev-alt_max_pkt_size[1] is 0.

I also attachted  a lsusb -v output for the Terratec Cinergy HTC Stick. 
I don't know, which of these endpoints the dvb-c part is, but it may be 
anyway usefull.


Regard,
Dennis

Bus 001 Device 009: ID 0ccd:00b2 TerraTec Electronic GmbH 
Device Descriptor:
  bLength18
  bDescriptorType 1
  bcdUSB   2.00
  bDeviceClass0 (Defined at Interface level)
  bDeviceSubClass 0 
  bDeviceProtocol   

Re: em28xx_isoc_dvb_max_packetsize for EM2884 (Terratec Cinergy HTC Stick)

2011-12-25 Thread Holger Nelson

Hi!

On Sun, 25 Dec 2011, Dennis Sperlich wrote:


I just tried, replacing
   max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev);
by
   max_dvb_packet_size = dev-alt_max_pkt_size[1];

but it did not work. Was this the correct replacement?

   printk(KERN_INFO dev-alt_max_pkt_size[1] is 
%i\n,dev-alt_max_pkt_size[1]);


then said, dev-alt_max_pkt_size[1] is 0.

I also attachted  a lsusb -v output for the Terratec Cinergy HTC Stick. I 
don't know, which of these endpoints the dvb-c part is, but it may be anyway 
usefull.


Is it possible, that dev-alt_max_pkt_size gets the maximum packet sizes 
for the analog video input endpoint (0x82 in lsusb output)? The patch 
below worked during a small test, but I doubt that it is the best way to 
do it.


While still looking at it: Is there a reason to allocate 32 bytes per 
alternate interface configuration if we only store one unsigned int per 
configuration in it? - I just copied the allocation code from above.


Holger

diff --git a/drivers/media/video/em28xx/em28xx-cards.c 
b/drivers/media/video/em28xx/em28xx-cards.c
index 1704da0..70866c5 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -3269,6 +3273,30 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
dev-alt_max_pkt_size[i] = size;
}

+   dev-alt_dvb_max_pkt_size = kmalloc(32 * dev-num_alt, GFP_KERNEL);
+
+   if (dev-alt_dvb_max_pkt_size == NULL) {
+   em28xx_errdev(out of memory!\n);
+   kfree(dev);
+   retval = -ENOMEM;
+   goto err;
+   }
+
+   for (i = 0; i  dev-num_alt ; i++) {
+   int ep;
+   for (ep = 0; ep  interface-altsetting[i].desc.bNumEndpoints; 
ep++) {
+   struct usb_host_endpoint *e = 
interface-altsetting[i].endpoint[ep];
+   if (e-desc.bEndpointAddress == 0x84) {
+   u16 tmp = le16_to_cpu(e-desc.wMaxPacketSize);
+   unsigned int size = tmp  0x7ff;
+   if (udev-speed == USB_SPEED_HIGH)
+   size = size * hb_mult(tmp);
+
+   dev-alt_dvb_max_pkt_size[i] = size;
+   }
+   }
+   }
+
if ((card[nr] = 0)  (card[nr]  em28xx_bcount))
dev-model = card[nr];

@@ -3281,6 +3309,7 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
retval = em28xx_init_dev(dev, udev, interface, nr);
if (retval) {
mutex_unlock(dev-lock);
+   kfree(dev-alt_dvb_max_pkt_size);
kfree(dev-alt_max_pkt_size);
kfree(dev);
goto err;
@@ -3365,6 +3394,7 @@ static void em28xx_usb_disconnect(struct usb_interface 
*interface)
em28xx_close_extension(dev);

if (!dev-users) {
+   kfree(dev-alt_dvb_max_pkt_size);
kfree(dev-alt_max_pkt_size);
kfree(dev);
}
diff --git a/drivers/media/video/em28xx/em28xx-core.c 
b/drivers/media/video/em28xx/em28xx-core.c
index 804a4ab..e7d3541 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1157,7 +1157,7 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
 * FIXME: same as em2874. 564 was enough for 22 Mbit DVB-T
 * but not enough for 44 Mbit DVB-C.
 */
-   packet_size = 752;
+   packet_size = dev-alt_dvb_max_pkt_size[1];
}

return packet_size;
diff --git a/drivers/media/video/em28xx/em28xx-video.c 
b/drivers/media/video/em28xx/em28xx-video.c
index 9b4557a..2491a2c 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -2254,6 +2254,7 @@ static int em28xx_v4l2_close(struct file *filp)
   free the remaining resources */
if (dev-state  DEV_DISCONNECTED) {
em28xx_release_resources(dev);
+   kfree(dev-alt_dvb_max_pkt_size);
kfree(dev-alt_max_pkt_size);
kfree(dev);
return 0;
diff --git a/drivers/media/video/em28xx/em28xx.h 
b/drivers/media/video/em28xx/em28xx.h
index b1199ef..793c85a 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -597,6 +597,7 @@ struct em28xx {
int max_pkt_size;   /* max packet size of isoc transaction */
int num_alt;/* Number of alternative settings */
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
+   unsigned int *alt_dvb_max_pkt_size;
struct urb *urb[EM28XX_NUM_BUFS];   /* urb for isoc transfers */
char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc
   transfer */