diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c index 46ed95483e22..95fd49a1d193 100644 --- a/drivers/media/usb/gspca/cpia1.c +++ b/drivers/media/usb/gspca/cpia1.c @@ -18,6 +18,8 @@ #include #include +#include +#include #include "gspca.h" @@ -1018,7 +1020,7 @@ static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) struct sd *sd = (struct sd *) gspca_dev; int currentexp = sd->params.exposure.coarseExpLo + sd->params.exposure.coarseExpHi * 256; - int ret, startexp; + int ret, startexp, lastbit; if (on) { int cj = sd->params.flickerControl.coarseJump; @@ -1028,6 +1030,9 @@ static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) sd->params.exposure.expMode = 2; sd->exposure_status = EXPOSURE_NORMAL; } + lastbit = find_last_bit((unsigned long*)¤texp, BITS_PER_TYPE(currentexp)); + if (sd->params.exposure.gain >= BITS_PER_TYPE(currentexp) - lastbit) + return -EINVAL; currentexp = currentexp << sd->params.exposure.gain; sd->params.exposure.gain = 0; /* round down current exposure to nearest value */