Commit b4bb4d42 authored by Johan Hovold's avatar Johan Hovold Committed by Mauro Carvalho Chehab

media: gspca/sunplus: fix zero-length control requests

The direction of the pipe argument must match the request-type direction
bit or control requests may fail depending on the host-controller-driver
implementation.

Control transfers without a data stage are treated as OUT requests by
the USB stack and should be using usb_sndctrlpipe(). Failing to do so
will now trigger a warning.

Fix the single zero-length control request which was using the
read-register helper, and update the helper so that zero-length reads
fail with an error message instead.

Fixes: 6a7eba24 ("V4L/DVB (8157): gspca: all subdrivers")
Cc: stable@vger.kernel.org      # 2.6.27
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 8ed339f2
...@@ -242,6 +242,10 @@ static void reg_r(struct gspca_dev *gspca_dev, ...@@ -242,6 +242,10 @@ static void reg_r(struct gspca_dev *gspca_dev,
gspca_err(gspca_dev, "reg_r: buffer overflow\n"); gspca_err(gspca_dev, "reg_r: buffer overflow\n");
return; return;
} }
if (len == 0) {
gspca_err(gspca_dev, "reg_r: zero-length read\n");
return;
}
if (gspca_dev->usb_err < 0) if (gspca_dev->usb_err < 0)
return; return;
ret = usb_control_msg(gspca_dev->dev, ret = usb_control_msg(gspca_dev->dev,
...@@ -250,7 +254,7 @@ static void reg_r(struct gspca_dev *gspca_dev, ...@@ -250,7 +254,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, index,
len ? gspca_dev->usb_buf : NULL, len, gspca_dev->usb_buf, len,
500); 500);
if (ret < 0) { if (ret < 0) {
pr_err("reg_r err %d\n", ret); pr_err("reg_r err %d\n", ret);
...@@ -727,7 +731,7 @@ static int sd_start(struct gspca_dev *gspca_dev) ...@@ -727,7 +731,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
case MegaImageVI: case MegaImageVI:
reg_w_riv(gspca_dev, 0xf0, 0, 0); reg_w_riv(gspca_dev, 0xf0, 0, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
reg_r(gspca_dev, 0xf0, 4, 0); reg_w_riv(gspca_dev, 0xf0, 4, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
break; break;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment