V4L/DVB: gspca - main: Stop the webcam when bandwidth too small
Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
832d0a9130
commit
e4dac289f0
|
@ -613,6 +613,37 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gspca_set_alt0(struct gspca_dev *gspca_dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (gspca_dev->alt == 0)
|
||||||
|
return 0;
|
||||||
|
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: both the queue and the usb locks should be held when calling this */
|
||||||
|
static void gspca_stream_off(struct gspca_dev *gspca_dev)
|
||||||
|
{
|
||||||
|
gspca_dev->streaming = 0;
|
||||||
|
if (gspca_dev->present) {
|
||||||
|
if (gspca_dev->sd_desc->stopN)
|
||||||
|
gspca_dev->sd_desc->stopN(gspca_dev);
|
||||||
|
destroy_urbs(gspca_dev);
|
||||||
|
gspca_input_destroy_urb(gspca_dev);
|
||||||
|
gspca_set_alt0(gspca_dev);
|
||||||
|
gspca_input_create_urb(gspca_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* always call stop0 to free the subdriver's resources */
|
||||||
|
if (gspca_dev->sd_desc->stop0)
|
||||||
|
gspca_dev->sd_desc->stop0(gspca_dev);
|
||||||
|
PDEBUG(D_STREAM, "stream off OK");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* look for an input transfer endpoint in an alternate setting
|
* look for an input transfer endpoint in an alternate setting
|
||||||
*/
|
*/
|
||||||
|
@ -838,8 +869,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
|
||||||
}
|
}
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
break;
|
break;
|
||||||
gspca_dev->streaming = 0;
|
gspca_stream_off(gspca_dev);
|
||||||
destroy_urbs(gspca_dev);
|
|
||||||
if (ret != -ENOSPC) {
|
if (ret != -ENOSPC) {
|
||||||
PDEBUG(D_ERR|D_STREAM,
|
PDEBUG(D_ERR|D_STREAM,
|
||||||
"usb_submit_urb alt %d err %d",
|
"usb_submit_urb alt %d err %d",
|
||||||
|
@ -869,37 +899,6 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gspca_set_alt0(struct gspca_dev *gspca_dev)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (gspca_dev->alt == 0)
|
|
||||||
return 0;
|
|
||||||
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
|
|
||||||
if (ret < 0)
|
|
||||||
PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note: both the queue and the usb locks should be held when calling this */
|
|
||||||
static void gspca_stream_off(struct gspca_dev *gspca_dev)
|
|
||||||
{
|
|
||||||
gspca_dev->streaming = 0;
|
|
||||||
if (gspca_dev->present) {
|
|
||||||
if (gspca_dev->sd_desc->stopN)
|
|
||||||
gspca_dev->sd_desc->stopN(gspca_dev);
|
|
||||||
destroy_urbs(gspca_dev);
|
|
||||||
gspca_input_destroy_urb(gspca_dev);
|
|
||||||
gspca_set_alt0(gspca_dev);
|
|
||||||
gspca_input_create_urb(gspca_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* always call stop0 to free the subdriver's resources */
|
|
||||||
if (gspca_dev->sd_desc->stop0)
|
|
||||||
gspca_dev->sd_desc->stop0(gspca_dev);
|
|
||||||
PDEBUG(D_STREAM, "stream off OK");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
|
static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
Loading…
Reference in New Issue