aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-10-09 03:17:42 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:40:31 -0500
commit205260102c5cef4180982eec88aaeb6934faf214 (patch)
tree51ae649d6776187e20981d18c3cae0a906bd1311 /drivers
parent6ca3f255f790764f9cfc41d3ac02823d83dfa5ac (diff)
V4L/DVB (13141): gspca_sq905c: once one frame is discarded it keeps discarding all frames
While checking all gspca sub drivers pkt_scan functions for a bug I found in 1 of them (and after checking also in another), I noticed a bug in the gspca_sq905c work queue function, once it has decided to start discarding a frame because the application is not reading fast enough (and thus returning buffers to fill fast enough), it never stops discarding. This patch fixes this by simply completely removing the "discarding" variable, if we need to discard the current frame because there is no buffer to store it, the "frame" pointer will be NULL, so that is all we need to check. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/sq905c.c23
1 files changed, 7 insertions, 16 deletions
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index 916892505432..81020f6f739e 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -119,7 +119,6 @@ static void sq905c_dostream(struct work_struct *work)
119 int bytes_left; /* bytes remaining in current frame. */ 119 int bytes_left; /* bytes remaining in current frame. */
120 int data_len; /* size to use for the next read. */ 120 int data_len; /* size to use for the next read. */
121 int act_len; 121 int act_len;
122 int discarding = 0; /* true if we failed to get space for frame. */
123 int packet_type; 122 int packet_type;
124 int ret; 123 int ret;
125 u8 *buffer; 124 u8 *buffer;
@@ -131,8 +130,6 @@ static void sq905c_dostream(struct work_struct *work)
131 } 130 }
132 131
133 while (gspca_dev->present && gspca_dev->streaming) { 132 while (gspca_dev->present && gspca_dev->streaming) {
134 if (!gspca_dev->present)
135 goto quit_stream;
136 /* Request the header, which tells the size to download */ 133 /* Request the header, which tells the size to download */
137 ret = usb_bulk_msg(gspca_dev->dev, 134 ret = usb_bulk_msg(gspca_dev->dev,
138 usb_rcvbulkpipe(gspca_dev->dev, 0x81), 135 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
@@ -150,16 +147,12 @@ static void sq905c_dostream(struct work_struct *work)
150 /* We keep the header. It has other information, too. */ 147 /* We keep the header. It has other information, too. */
151 packet_type = FIRST_PACKET; 148 packet_type = FIRST_PACKET;
152 frame = gspca_get_i_frame(gspca_dev); 149 frame = gspca_get_i_frame(gspca_dev);
153 if (frame && !discarding) { 150 if (frame)
154 gspca_frame_add(gspca_dev, packet_type, 151 gspca_frame_add(gspca_dev, packet_type,
155 frame, buffer, FRAME_HEADER_LEN); 152 frame, buffer, FRAME_HEADER_LEN);
156 } else 153 while (bytes_left > 0 && gspca_dev->present) {
157 discarding = 1;
158 while (bytes_left > 0) {
159 data_len = bytes_left > SQ905C_MAX_TRANSFER ? 154 data_len = bytes_left > SQ905C_MAX_TRANSFER ?
160 SQ905C_MAX_TRANSFER : bytes_left; 155 SQ905C_MAX_TRANSFER : bytes_left;
161 if (!gspca_dev->present)
162 goto quit_stream;
163 ret = usb_bulk_msg(gspca_dev->dev, 156 ret = usb_bulk_msg(gspca_dev->dev,
164 usb_rcvbulkpipe(gspca_dev->dev, 0x81), 157 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
165 buffer, data_len, &act_len, 158 buffer, data_len, &act_len,
@@ -174,19 +167,17 @@ static void sq905c_dostream(struct work_struct *work)
174 packet_type = LAST_PACKET; 167 packet_type = LAST_PACKET;
175 else 168 else
176 packet_type = INTER_PACKET; 169 packet_type = INTER_PACKET;
177 frame = gspca_get_i_frame(gspca_dev); 170 if (frame)
178 if (frame && !discarding)
179 gspca_frame_add(gspca_dev, packet_type, 171 gspca_frame_add(gspca_dev, packet_type,
180 frame, buffer, data_len); 172 frame, buffer, data_len);
181 else
182 discarding = 1;
183 } 173 }
184 } 174 }
185quit_stream: 175quit_stream:
186 mutex_lock(&gspca_dev->usb_lock); 176 if (gspca_dev->present) {
187 if (gspca_dev->present) 177 mutex_lock(&gspca_dev->usb_lock);
188 sq905c_command(gspca_dev, SQ905C_CLEAR, 0); 178 sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
189 mutex_unlock(&gspca_dev->usb_lock); 179 mutex_unlock(&gspca_dev->usb_lock);
180 }
190 kfree(buffer); 181 kfree(buffer);
191} 182}
192 183