diff options
author | Jean-François Moine <moinejf@free.fr> | 2010-04-09 05:11:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:57:57 -0400 |
commit | e4dac289f01da80d7966a123bc1ea97be199ba4f (patch) | |
tree | 410f0ff24c6f83263dd5fc68a4319d7d9d4f581e | |
parent | 832d0a9130c18b9ee4b671c46763b972eb2a2568 (diff) |
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>
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 65 |
1 files changed, 32 insertions, 33 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 9c9d7ea7e62..e8d08f88795 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -613,6 +613,37 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) | |||
613 | } | 613 | } |
614 | } | 614 | } |
615 | 615 | ||
616 | static int gspca_set_alt0(struct gspca_dev *gspca_dev) | ||
617 | { | ||
618 | int ret; | ||
619 | |||
620 | if (gspca_dev->alt == 0) | ||
621 | return 0; | ||
622 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | ||
623 | if (ret < 0) | ||
624 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); | ||
625 | return ret; | ||
626 | } | ||
627 | |||
628 | /* Note: both the queue and the usb locks should be held when calling this */ | ||
629 | static void gspca_stream_off(struct gspca_dev *gspca_dev) | ||
630 | { | ||
631 | gspca_dev->streaming = 0; | ||
632 | if (gspca_dev->present) { | ||
633 | if (gspca_dev->sd_desc->stopN) | ||
634 | gspca_dev->sd_desc->stopN(gspca_dev); | ||
635 | destroy_urbs(gspca_dev); | ||
636 | gspca_input_destroy_urb(gspca_dev); | ||
637 | gspca_set_alt0(gspca_dev); | ||
638 | gspca_input_create_urb(gspca_dev); | ||
639 | } | ||
640 | |||
641 | /* always call stop0 to free the subdriver's resources */ | ||
642 | if (gspca_dev->sd_desc->stop0) | ||
643 | gspca_dev->sd_desc->stop0(gspca_dev); | ||
644 | PDEBUG(D_STREAM, "stream off OK"); | ||
645 | } | ||
646 | |||
616 | /* | 647 | /* |
617 | * look for an input transfer endpoint in an alternate setting | 648 | * look for an input transfer endpoint in an alternate setting |
618 | */ | 649 | */ |
@@ -838,8 +869,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
838 | } | 869 | } |
839 | if (ret >= 0) | 870 | if (ret >= 0) |
840 | break; | 871 | break; |
841 | gspca_dev->streaming = 0; | 872 | gspca_stream_off(gspca_dev); |
842 | destroy_urbs(gspca_dev); | ||
843 | if (ret != -ENOSPC) { | 873 | if (ret != -ENOSPC) { |
844 | PDEBUG(D_ERR|D_STREAM, | 874 | PDEBUG(D_ERR|D_STREAM, |
845 | "usb_submit_urb alt %d err %d", | 875 | "usb_submit_urb alt %d err %d", |
@@ -869,37 +899,6 @@ out: | |||
869 | return ret; | 899 | return ret; |
870 | } | 900 | } |
871 | 901 | ||
872 | static int gspca_set_alt0(struct gspca_dev *gspca_dev) | ||
873 | { | ||
874 | int ret; | ||
875 | |||
876 | if (gspca_dev->alt == 0) | ||
877 | return 0; | ||
878 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | ||
879 | if (ret < 0) | ||
880 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); | ||
881 | return ret; | ||
882 | } | ||
883 | |||
884 | /* Note: both the queue and the usb locks should be held when calling this */ | ||
885 | static void gspca_stream_off(struct gspca_dev *gspca_dev) | ||
886 | { | ||
887 | gspca_dev->streaming = 0; | ||
888 | if (gspca_dev->present) { | ||
889 | if (gspca_dev->sd_desc->stopN) | ||
890 | gspca_dev->sd_desc->stopN(gspca_dev); | ||
891 | destroy_urbs(gspca_dev); | ||
892 | gspca_input_destroy_urb(gspca_dev); | ||
893 | gspca_set_alt0(gspca_dev); | ||
894 | gspca_input_create_urb(gspca_dev); | ||
895 | } | ||
896 | |||
897 | /* always call stop0 to free the subdriver's resources */ | ||
898 | if (gspca_dev->sd_desc->stop0) | ||
899 | gspca_dev->sd_desc->stop0(gspca_dev); | ||
900 | PDEBUG(D_STREAM, "stream off OK"); | ||
901 | } | ||
902 | |||
903 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) | 902 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) |
904 | { | 903 | { |
905 | int i; | 904 | int i; |