aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sq905.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-10-05 04:58:18 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:40:30 -0500
commit8519110040ca98dfbc89c473921cca390c81460c (patch)
treeddb94a5d1cf726c63bc81a1f84c3804763421d80 /drivers/media/video/gspca/sq905.c
parent930bf78c20187f3cbbf0775cd317616c6b681a8a (diff)
V4L/DVB (13138): gspca_sq905: cleanup sq905_dostream
-Remove use of unneeded discarding variable -Cleanup locking to only take usb_lock around access to the control endpoint, by no longer taking the lock around the bulk transfer (which takes most of the time) we can remove the msleep(1) which was needed to give the gspca core a chance to grab the usb_lock to signal us to stop. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/sq905.c')
-rw-r--r--drivers/media/video/gspca/sq905.c56
1 files changed, 26 insertions, 30 deletions
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 715a68f0156e..547d1fd5191d 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -168,18 +168,22 @@ static int sq905_ack_frame(struct gspca_dev *gspca_dev)
168 * request and read a block of data - see warning on sq905_command. 168 * request and read a block of data - see warning on sq905_command.
169 */ 169 */
170static int 170static int
171sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size) 171sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
172{ 172{
173 int ret; 173 int ret;
174 int act_len; 174 int act_len;
175 175
176 gspca_dev->usb_buf[0] = '\0'; 176 gspca_dev->usb_buf[0] = '\0';
177 if (need_lock)
178 mutex_lock(&gspca_dev->usb_lock);
177 ret = usb_control_msg(gspca_dev->dev, 179 ret = usb_control_msg(gspca_dev->dev,
178 usb_sndctrlpipe(gspca_dev->dev, 0), 180 usb_sndctrlpipe(gspca_dev->dev, 0),
179 USB_REQ_SYNCH_FRAME, /* request */ 181 USB_REQ_SYNCH_FRAME, /* request */
180 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 182 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
181 SQ905_BULK_READ, size, gspca_dev->usb_buf, 183 SQ905_BULK_READ, size, gspca_dev->usb_buf,
182 1, SQ905_CMD_TIMEOUT); 184 1, SQ905_CMD_TIMEOUT);
185 if (need_lock)
186 mutex_unlock(&gspca_dev->usb_lock);
183 if (ret < 0) { 187 if (ret < 0) {
184 PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); 188 PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
185 return ret; 189 return ret;
@@ -214,7 +218,6 @@ static void sq905_dostream(struct work_struct *work)
214 int bytes_left; /* bytes remaining in current frame. */ 218 int bytes_left; /* bytes remaining in current frame. */
215 int data_len; /* size to use for the next read. */ 219 int data_len; /* size to use for the next read. */
216 int header_read; /* true if we have already read the frame header. */ 220 int header_read; /* true if we have already read the frame header. */
217 int discarding; /* true if we failed to get space for frame. */
218 int packet_type; 221 int packet_type;
219 int frame_sz; 222 int frame_sz;
220 int ret; 223 int ret;
@@ -222,7 +225,6 @@ static void sq905_dostream(struct work_struct *work)
222 u8 *buffer; 225 u8 *buffer;
223 226
224 buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); 227 buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
225 mutex_lock(&gspca_dev->usb_lock);
226 if (!buffer) { 228 if (!buffer) {
227 PDEBUG(D_ERR, "Couldn't allocate USB buffer"); 229 PDEBUG(D_ERR, "Couldn't allocate USB buffer");
228 goto quit_stream; 230 goto quit_stream;
@@ -232,28 +234,22 @@ static void sq905_dostream(struct work_struct *work)
232 + FRAME_HEADER_LEN; 234 + FRAME_HEADER_LEN;
233 235
234 while (gspca_dev->present && gspca_dev->streaming) { 236 while (gspca_dev->present && gspca_dev->streaming) {
235 /* Need a short delay to ensure streaming flag was set by
236 * gspca and to make sure gspca can grab the mutex. */
237 mutex_unlock(&gspca_dev->usb_lock);
238 msleep(1);
239
240 /* request some data and then read it until we have 237 /* request some data and then read it until we have
241 * a complete frame. */ 238 * a complete frame. */
242 bytes_left = frame_sz; 239 bytes_left = frame_sz;
243 header_read = 0; 240 header_read = 0;
244 discarding = 0;
245 241
246 while (bytes_left > 0) { 242 /* Note we do not check for gspca_dev->streaming here, as
243 we must finish reading an entire frame, otherwise the
244 next time we stream we start reading in the middle of a
245 frame. */
246 while (bytes_left > 0 && gspca_dev->present) {
247 data_len = bytes_left > SQ905_MAX_TRANSFER ? 247 data_len = bytes_left > SQ905_MAX_TRANSFER ?
248 SQ905_MAX_TRANSFER : bytes_left; 248 SQ905_MAX_TRANSFER : bytes_left;
249 mutex_lock(&gspca_dev->usb_lock); 249 ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
250 if (!gspca_dev->present)
251 goto quit_stream;
252 ret = sq905_read_data(gspca_dev, buffer, data_len);
253 if (ret < 0) 250 if (ret < 0)
254 goto quit_stream; 251 goto quit_stream;
255 mutex_unlock(&gspca_dev->usb_lock); 252 PDEBUG(D_PACK,
256 PDEBUG(D_STREAM,
257 "Got %d bytes out of %d for frame", 253 "Got %d bytes out of %d for frame",
258 data_len, bytes_left); 254 data_len, bytes_left);
259 bytes_left -= data_len; 255 bytes_left -= data_len;
@@ -271,7 +267,7 @@ static void sq905_dostream(struct work_struct *work)
271 packet_type = INTER_PACKET; 267 packet_type = INTER_PACKET;
272 } 268 }
273 frame = gspca_get_i_frame(gspca_dev); 269 frame = gspca_get_i_frame(gspca_dev);
274 if (frame && !discarding) { 270 if (frame) {
275 frame = gspca_frame_add(gspca_dev, packet_type, 271 frame = gspca_frame_add(gspca_dev, packet_type,
276 frame, data, data_len); 272 frame, data, data_len);
277 /* If entire frame fits in one packet we still 273 /* If entire frame fits in one packet we still
@@ -281,23 +277,23 @@ static void sq905_dostream(struct work_struct *work)
281 frame = gspca_frame_add(gspca_dev, 277 frame = gspca_frame_add(gspca_dev,
282 LAST_PACKET, 278 LAST_PACKET,
283 frame, data, 0); 279 frame, data, 0);
284 } else {
285 discarding = 1;
286 } 280 }
287 } 281 }
288 /* acknowledge the frame */ 282 if (gspca_dev->present) {
289 mutex_lock(&gspca_dev->usb_lock); 283 /* acknowledge the frame */
290 if (!gspca_dev->present) 284 mutex_lock(&gspca_dev->usb_lock);
291 goto quit_stream; 285 ret = sq905_ack_frame(gspca_dev);
292 ret = sq905_ack_frame(gspca_dev); 286 mutex_unlock(&gspca_dev->usb_lock);
293 if (ret < 0) 287 if (ret < 0)
294 goto quit_stream; 288 goto quit_stream;
289 }
295 } 290 }
296quit_stream: 291quit_stream:
297 /* the usb_lock is already acquired */ 292 if (gspca_dev->present) {
298 if (gspca_dev->present) 293 mutex_lock(&gspca_dev->usb_lock);
299 sq905_command(gspca_dev, SQ905_CLEAR); 294 sq905_command(gspca_dev, SQ905_CLEAR);
300 mutex_unlock(&gspca_dev->usb_lock); 295 mutex_unlock(&gspca_dev->usb_lock);
296 }
301 kfree(buffer); 297 kfree(buffer);
302} 298}
303 299
@@ -346,7 +342,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
346 ret = sq905_command(gspca_dev, SQ905_ID); 342 ret = sq905_command(gspca_dev, SQ905_ID);
347 if (ret < 0) 343 if (ret < 0)
348 return ret; 344 return ret;
349 ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4); 345 ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0);
350 if (ret < 0) 346 if (ret < 0)
351 return ret; 347 return ret;
352 /* usb_buf is allocated with kmalloc so is aligned. 348 /* usb_buf is allocated with kmalloc so is aligned.