diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-12-23 13:25:38 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-12-23 17:24:30 -0200 |
commit | 8b2aea7878f64814544d0527c659011949d52358 (patch) | |
tree | 92b30b2feedf8d1a6db53140b97e1042444209f4 | |
parent | a3efa1cc0e067675ffa2d2c357cbe1da0db4653b (diff) |
[media] em28xx: prefer bulk mode on webcams
Using bulk mode allows more than one webcam, as the maximum fps
is low at 640x480 resolution. So, prefer it, if the device is
a webcam.
Tested with Silvercrest 1.3 Mpixel webcam (em2710) on both bulk and isoc
modes.
Tested analog with HVR-950 model 65201/A1C0 (em2883), where only ISOC
endpoints are available for both DVB and Analog.
Tested on Hauppauge WinTV USB 2 (em2840) on both bulk and isoc modes.
It should be noticed that enabling bulk mode by default with TV boards
is a bad idea; what happens is that, while with ISOC the USB logic will
prevent the concurrent usage of two devices that spends more than 100%
of the USB2 traffic, it doesn't care with bulk transfers.
On my tests, I started two streams, one with a WinTV at 640x480x30fps
and the other one with a Silvercrest webcam at 640x480, on a lower fps)
both on bulk mode. One of the streams always silently failed.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-cards.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 1f90a8a8181..ad6c800d9a4 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -61,9 +61,9 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; module_param_array(card, int, NULL, 0444); MODULE_PARM_DESC(card, "card type"); -static unsigned int prefer_bulk; +static int prefer_bulk = -1; module_param(prefer_bulk, int, 0444); -MODULE_PARM_DESC(prefer_bulk, "prefer USB bulk transfers"); +MODULE_PARM_DESC(prefer_bulk, "prefer USB bulk transfers (-1 = auto, 0 = isoc, 1 = bulk)"); /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */ @@ -3170,7 +3170,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, struct em28xx *dev = NULL; int retval; bool has_audio = false, has_video = false, has_dvb = false; - int i, nr; + int i, nr, try_bulk; const int ifnum = interface->altsetting[0].desc.bInterfaceNumber; char *speed; @@ -3344,14 +3344,6 @@ static int em28xx_usb_probe(struct usb_interface *interface, goto err_free; } - /* Select USB transfer types to use */ - if (has_video && - (!dev->analog_ep_isoc || (prefer_bulk && dev->analog_ep_bulk))) - dev->analog_xfer_bulk = 1; - if (has_dvb && - (!dev->dvb_ep_isoc || (prefer_bulk && dev->dvb_ep_bulk))) - dev->dvb_xfer_bulk = 1; - dev->devno = nr; dev->model = id->driver_info; dev->alt = -1; @@ -3402,7 +3394,29 @@ static int em28xx_usb_probe(struct usb_interface *interface, goto unlock_and_free; } + if (prefer_bulk < 0) { + if (dev->board.is_webcam) + try_bulk = 1; + else + try_bulk = 0; + } else { + try_bulk = prefer_bulk > 0; + } + + /* Select USB transfer types to use */ + if (has_video) { + if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) + dev->analog_xfer_bulk = 1; + em28xx_info("analog set to %s mode.\n", + dev->analog_xfer_bulk ? "bulk" : "isoc"); + } if (has_dvb) { + if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) + dev->dvb_xfer_bulk = 1; + + em28xx_info("dvb set to %s mode.\n", + dev->dvb_xfer_bulk ? "bulk" : "isoc"); + /* pre-allocate DVB usb transfer buffers */ if (dev->dvb_xfer_bulk) { retval = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE, |