Commit bc46bae6 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

[media] gspca_xirlink_cit: various usb bandwidth allocation improvements / fixes

The following usb bandwidth allocation changes were made to the ibm netcam
pro code:
- Don't restart negotiation at max packet size on stop0, as that gets called
  by gspca_main during negotiation. Move this to sd_isoc_init.
- Don't ask for full bandwidth when running at 160x120, that does not need
  full bandwidth
- Make minimum acceptable bandwidth depend upon resolution

[mchehab@redhat.com: Fix CodingStyle problems at switch statements]
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2661da47
...@@ -2769,16 +2769,55 @@ static int sd_start(struct gspca_dev *gspca_dev) ...@@ -2769,16 +2769,55 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0; return 0;
} }
static int sd_isoc_init(struct gspca_dev *gspca_dev)
{
struct usb_host_interface *alt;
int max_packet_size;
switch (gspca_dev->width) {
case 160:
max_packet_size = 450;
break;
case 176:
max_packet_size = 600;
break;
default:
max_packet_size = 1022;
break;
}
/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
return 0;
}
static int sd_isoc_nego(struct gspca_dev *gspca_dev) static int sd_isoc_nego(struct gspca_dev *gspca_dev)
{ {
int ret, packet_size; int ret, packet_size, min_packet_size;
struct usb_host_interface *alt; struct usb_host_interface *alt;
switch (gspca_dev->width) {
case 160:
min_packet_size = 200;
break;
case 176:
min_packet_size = 266;
break;
default:
min_packet_size = 400;
break;
}
alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
packet_size -= 100; if (packet_size <= min_packet_size)
if (packet_size < 300)
return -EIO; return -EIO;
packet_size -= 100;
if (packet_size < min_packet_size)
packet_size = min_packet_size;
alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
...@@ -2796,15 +2835,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev) ...@@ -2796,15 +2835,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_host_interface *alt;
/* We cannot use gspca_dev->present here as that is not set when /* We cannot use gspca_dev->present here as that is not set when
sd_init gets called and we get called from sd_init */ sd_init gets called and we get called from sd_init */
if (!gspca_dev->dev) if (!gspca_dev->dev)
return; return;
alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
switch (sd->model) { switch (sd->model) {
case CIT_MODEL0: case CIT_MODEL0:
/* HDG windows does this, but it causes the cams autogain to /* HDG windows does this, but it causes the cams autogain to
...@@ -2859,10 +2895,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) ...@@ -2859,10 +2895,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
restarting the stream after this */ restarting the stream after this */
/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
cit_write_reg(gspca_dev, 0x00c0, 0x0100); cit_write_reg(gspca_dev, 0x00c0, 0x0100);
/* Start isoc bandwidth "negotiation" at max isoc bandwith
next stream start */
alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(1022);
break; break;
} }
} }
...@@ -3179,6 +3211,7 @@ static const struct sd_desc sd_desc_isoc_nego = { ...@@ -3179,6 +3211,7 @@ static const struct sd_desc sd_desc_isoc_nego = {
.config = sd_config, .config = sd_config,
.init = sd_init, .init = sd_init,
.start = sd_start, .start = sd_start,
.isoc_init = sd_isoc_init,
.isoc_nego = sd_isoc_nego, .isoc_nego = sd_isoc_nego,
.stopN = sd_stopN, .stopN = sd_stopN,
.stop0 = sd_stop0, .stop0 = sd_stop0,
......
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