aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-09-09 05:30:02 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-09-13 16:42:17 -0400
commit345321dc9c52b774f42c934339f9b3e2f0a39395 (patch)
treea86e8fde0d50634c467c0c9d75b37776037e27d7 /drivers/media
parent8c96f0a207bedb6f06089fde9adc7abe8136a087 (diff)
[media] gspca: Don't set gspca_dev->dev to NULL before stop0
In commit a3d6e8cc0e6ddc8b3cfdeb3c979f07ed1aa528b3 gspca_dev->dev is set to NULL on disconnect, before calling stop0. The plan was to get rid of gspca_dev->present and instead simply check for gspca_dev->dev everywhere where we were checking for present. This should be race free since all users of gspca_dev->dev hold the usb_lock, or so I thought. But I was wrong, drivers which use a work-queue + synchronous bulk transfers to get the video data don't hold the usb_lock while doing so, their stop0 callbacks stop the workqueue, so they won't be using gspca_dev->dev anymore after the stop0 call, but they might be dereferincing it before, so we should not set gspca_dev->dev to NULL on disconnect before calling stop0. This also means that the workqueue functions in these drivers cannot use gspca_dev->dev to check if they need to stop because of disconnection, so we will need to keep gspca_dev->present around, and set that to 0 on disconnect, before calling stop0. Unfortunately as part of the plan to remove gspca_dev->present, these workqueues where already moved over to checking for gspca_dev->dev instead of gspca_dev->present as part of commit 254902b01d2acc6aced99ec17caa4c6cd890cdea, so this patch also reverts those parts of that commit. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/usb/gspca/finepix.c6
-rw-r--r--drivers/media/usb/gspca/gspca.c3
-rw-r--r--drivers/media/usb/gspca/jl2005bcd.c6
-rw-r--r--drivers/media/usb/gspca/sq905.c8
-rw-r--r--drivers/media/usb/gspca/sq905c.c6
-rw-r--r--drivers/media/usb/gspca/vicam.c4
-rw-r--r--drivers/media/usb/gspca/xirlink_cit.c4
-rw-r--r--drivers/media/usb/gspca/zc3xx.c4
8 files changed, 19 insertions, 22 deletions
diff --git a/drivers/media/usb/gspca/finepix.c b/drivers/media/usb/gspca/finepix.c
index c8f2201cc35..04807eee777 100644
--- a/drivers/media/usb/gspca/finepix.c
+++ b/drivers/media/usb/gspca/finepix.c
@@ -94,7 +94,7 @@ static void dostream(struct work_struct *work)
94 94
95 /* loop reading a frame */ 95 /* loop reading a frame */
96again: 96again:
97 while (gspca_dev->dev && gspca_dev->streaming) { 97 while (gspca_dev->present && gspca_dev->streaming) {
98#ifdef CONFIG_PM 98#ifdef CONFIG_PM
99 if (gspca_dev->frozen) 99 if (gspca_dev->frozen)
100 break; 100 break;
@@ -110,7 +110,7 @@ again:
110 if (gspca_dev->frozen) 110 if (gspca_dev->frozen)
111 break; 111 break;
112#endif 112#endif
113 if (!gspca_dev->dev || !gspca_dev->streaming) 113 if (!gspca_dev->present || !gspca_dev->streaming)
114 break; 114 break;
115 115
116 /* the frame comes in parts */ 116 /* the frame comes in parts */
@@ -129,7 +129,7 @@ again:
129 if (gspca_dev->frozen) 129 if (gspca_dev->frozen)
130 goto out; 130 goto out;
131#endif 131#endif
132 if (!gspca_dev->dev || !gspca_dev->streaming) 132 if (!gspca_dev->present || !gspca_dev->streaming)
133 goto out; 133 goto out;
134 if (len < FPIX_MAX_TRANSFER || 134 if (len < FPIX_MAX_TRANSFER ||
135 (data[len - 2] == 0xff && 135 (data[len - 2] == 0xff &&
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index d4e8343f5b1..7cce0f201d7 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -2358,8 +2358,6 @@ void gspca_disconnect(struct usb_interface *intf)
2358 2358
2359 mutex_lock(&gspca_dev->usb_lock); 2359 mutex_lock(&gspca_dev->usb_lock);
2360 2360
2361 usb_set_intfdata(intf, NULL);
2362 gspca_dev->dev = NULL;
2363 gspca_dev->present = 0; 2361 gspca_dev->present = 0;
2364 destroy_urbs(gspca_dev); 2362 destroy_urbs(gspca_dev);
2365 2363
@@ -2375,6 +2373,7 @@ void gspca_disconnect(struct usb_interface *intf)
2375 if (gspca_dev->sd_desc->stop0 && gspca_dev->streaming) 2373 if (gspca_dev->sd_desc->stop0 && gspca_dev->streaming)
2376 gspca_dev->sd_desc->stop0(gspca_dev); 2374 gspca_dev->sd_desc->stop0(gspca_dev);
2377 gspca_dev->streaming = 0; 2375 gspca_dev->streaming = 0;
2376 gspca_dev->dev = NULL;
2378 wake_up_interruptible(&gspca_dev->wq); 2377 wake_up_interruptible(&gspca_dev->wq);
2379 2378
2380 v4l2_device_disconnect(&gspca_dev->v4l2_dev); 2379 v4l2_device_disconnect(&gspca_dev->v4l2_dev);
diff --git a/drivers/media/usb/gspca/jl2005bcd.c b/drivers/media/usb/gspca/jl2005bcd.c
index 234777116e5..c4b4a9598db 100644
--- a/drivers/media/usb/gspca/jl2005bcd.c
+++ b/drivers/media/usb/gspca/jl2005bcd.c
@@ -335,7 +335,7 @@ static void jl2005c_dostream(struct work_struct *work)
335 goto quit_stream; 335 goto quit_stream;
336 } 336 }
337 337
338 while (gspca_dev->dev && gspca_dev->streaming) { 338 while (gspca_dev->present && gspca_dev->streaming) {
339#ifdef CONFIG_PM 339#ifdef CONFIG_PM
340 if (gspca_dev->frozen) 340 if (gspca_dev->frozen)
341 break; 341 break;
@@ -371,7 +371,7 @@ static void jl2005c_dostream(struct work_struct *work)
371 buffer, act_len); 371 buffer, act_len);
372 header_read = 1; 372 header_read = 1;
373 } 373 }
374 while (bytes_left > 0 && gspca_dev->dev) { 374 while (bytes_left > 0 && gspca_dev->present) {
375 data_len = bytes_left > JL2005C_MAX_TRANSFER ? 375 data_len = bytes_left > JL2005C_MAX_TRANSFER ?
376 JL2005C_MAX_TRANSFER : bytes_left; 376 JL2005C_MAX_TRANSFER : bytes_left;
377 ret = usb_bulk_msg(gspca_dev->dev, 377 ret = usb_bulk_msg(gspca_dev->dev,
@@ -394,7 +394,7 @@ static void jl2005c_dostream(struct work_struct *work)
394 } 394 }
395 } 395 }
396quit_stream: 396quit_stream:
397 if (gspca_dev->dev) { 397 if (gspca_dev->present) {
398 mutex_lock(&gspca_dev->usb_lock); 398 mutex_lock(&gspca_dev->usb_lock);
399 jl2005c_stop(gspca_dev); 399 jl2005c_stop(gspca_dev);
400 mutex_unlock(&gspca_dev->usb_lock); 400 mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c
index a8ac97931ad..2e05acab304 100644
--- a/drivers/media/usb/gspca/sq905.c
+++ b/drivers/media/usb/gspca/sq905.c
@@ -232,7 +232,7 @@ static void sq905_dostream(struct work_struct *work)
232 frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage 232 frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage
233 + FRAME_HEADER_LEN; 233 + FRAME_HEADER_LEN;
234 234
235 while (gspca_dev->dev && gspca_dev->streaming) { 235 while (gspca_dev->present && gspca_dev->streaming) {
236#ifdef CONFIG_PM 236#ifdef CONFIG_PM
237 if (gspca_dev->frozen) 237 if (gspca_dev->frozen)
238 break; 238 break;
@@ -246,7 +246,7 @@ static void sq905_dostream(struct work_struct *work)
246 we must finish reading an entire frame, otherwise the 246 we must finish reading an entire frame, otherwise the
247 next time we stream we start reading in the middle of a 247 next time we stream we start reading in the middle of a
248 frame. */ 248 frame. */
249 while (bytes_left > 0 && gspca_dev->dev) { 249 while (bytes_left > 0 && gspca_dev->present) {
250 data_len = bytes_left > SQ905_MAX_TRANSFER ? 250 data_len = bytes_left > SQ905_MAX_TRANSFER ?
251 SQ905_MAX_TRANSFER : bytes_left; 251 SQ905_MAX_TRANSFER : bytes_left;
252 ret = sq905_read_data(gspca_dev, buffer, data_len, 1); 252 ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
@@ -278,7 +278,7 @@ static void sq905_dostream(struct work_struct *work)
278 gspca_frame_add(gspca_dev, LAST_PACKET, 278 gspca_frame_add(gspca_dev, LAST_PACKET,
279 NULL, 0); 279 NULL, 0);
280 } 280 }
281 if (gspca_dev->dev) { 281 if (gspca_dev->present) {
282 /* acknowledge the frame */ 282 /* acknowledge the frame */
283 mutex_lock(&gspca_dev->usb_lock); 283 mutex_lock(&gspca_dev->usb_lock);
284 ret = sq905_ack_frame(gspca_dev); 284 ret = sq905_ack_frame(gspca_dev);
@@ -288,7 +288,7 @@ static void sq905_dostream(struct work_struct *work)
288 } 288 }
289 } 289 }
290quit_stream: 290quit_stream:
291 if (gspca_dev->dev) { 291 if (gspca_dev->present) {
292 mutex_lock(&gspca_dev->usb_lock); 292 mutex_lock(&gspca_dev->usb_lock);
293 sq905_command(gspca_dev, SQ905_CLEAR); 293 sq905_command(gspca_dev, SQ905_CLEAR);
294 mutex_unlock(&gspca_dev->usb_lock); 294 mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/usb/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c
index 70fae6982e9..784620c102b 100644
--- a/drivers/media/usb/gspca/sq905c.c
+++ b/drivers/media/usb/gspca/sq905c.c
@@ -150,7 +150,7 @@ static void sq905c_dostream(struct work_struct *work)
150 goto quit_stream; 150 goto quit_stream;
151 } 151 }
152 152
153 while (gspca_dev->dev && gspca_dev->streaming) { 153 while (gspca_dev->present && gspca_dev->streaming) {
154#ifdef CONFIG_PM 154#ifdef CONFIG_PM
155 if (gspca_dev->frozen) 155 if (gspca_dev->frozen)
156 break; 156 break;
@@ -173,7 +173,7 @@ static void sq905c_dostream(struct work_struct *work)
173 packet_type = FIRST_PACKET; 173 packet_type = FIRST_PACKET;
174 gspca_frame_add(gspca_dev, packet_type, 174 gspca_frame_add(gspca_dev, packet_type,
175 buffer, FRAME_HEADER_LEN); 175 buffer, FRAME_HEADER_LEN);
176 while (bytes_left > 0 && gspca_dev->dev) { 176 while (bytes_left > 0 && gspca_dev->present) {
177 data_len = bytes_left > SQ905C_MAX_TRANSFER ? 177 data_len = bytes_left > SQ905C_MAX_TRANSFER ?
178 SQ905C_MAX_TRANSFER : bytes_left; 178 SQ905C_MAX_TRANSFER : bytes_left;
179 ret = usb_bulk_msg(gspca_dev->dev, 179 ret = usb_bulk_msg(gspca_dev->dev,
@@ -195,7 +195,7 @@ static void sq905c_dostream(struct work_struct *work)
195 } 195 }
196 } 196 }
197quit_stream: 197quit_stream:
198 if (gspca_dev->dev) { 198 if (gspca_dev->present) {
199 mutex_lock(&gspca_dev->usb_lock); 199 mutex_lock(&gspca_dev->usb_lock);
200 sq905c_command(gspca_dev, SQ905C_CLEAR, 0); 200 sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
201 mutex_unlock(&gspca_dev->usb_lock); 201 mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/usb/gspca/vicam.c b/drivers/media/usb/gspca/vicam.c
index b1a64b91266..57d88f70c39 100644
--- a/drivers/media/usb/gspca/vicam.c
+++ b/drivers/media/usb/gspca/vicam.c
@@ -194,7 +194,7 @@ static void vicam_dostream(struct work_struct *work)
194 goto exit; 194 goto exit;
195 } 195 }
196 196
197 while (gspca_dev->dev && gspca_dev->streaming) { 197 while (gspca_dev->present && gspca_dev->streaming) {
198#ifdef CONFIG_PM 198#ifdef CONFIG_PM
199 if (gspca_dev->frozen) 199 if (gspca_dev->frozen)
200 break; 200 break;
@@ -299,7 +299,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
299 dev->work_thread = NULL; 299 dev->work_thread = NULL;
300 mutex_lock(&gspca_dev->usb_lock); 300 mutex_lock(&gspca_dev->usb_lock);
301 301
302 if (gspca_dev->dev) 302 if (gspca_dev->present)
303 vicam_set_camera_power(gspca_dev, 0); 303 vicam_set_camera_power(gspca_dev, 0);
304} 304}
305 305
diff --git a/drivers/media/usb/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c
index 13b8d395d21..d4b23c9bf90 100644
--- a/drivers/media/usb/gspca/xirlink_cit.c
+++ b/drivers/media/usb/gspca/xirlink_cit.c
@@ -2697,9 +2697,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2697{ 2697{
2698 struct sd *sd = (struct sd *) gspca_dev; 2698 struct sd *sd = (struct sd *) gspca_dev;
2699 2699
2700 /* We cannot use gspca_dev->present here as that is not set when 2700 if (!gspca_dev->present)
2701 sd_init gets called and we get called from sd_init */
2702 if (!gspca_dev->dev)
2703 return; 2701 return;
2704 2702
2705 switch (sd->model) { 2703 switch (sd->model) {
diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c
index f0bacee33ef..234d9eaa8ee 100644
--- a/drivers/media/usb/gspca/zc3xx.c
+++ b/drivers/media/usb/gspca/zc3xx.c
@@ -5950,7 +5950,7 @@ static void transfer_update(struct work_struct *work)
5950 if (gspca_dev->frozen) 5950 if (gspca_dev->frozen)
5951 goto err; 5951 goto err;
5952#endif 5952#endif
5953 if (!gspca_dev->dev || !gspca_dev->streaming) 5953 if (!gspca_dev->present || !gspca_dev->streaming)
5954 goto err; 5954 goto err;
5955 5955
5956 /* Bit 0 of register 11 indicates FIFO overflow */ 5956 /* Bit 0 of register 11 indicates FIFO overflow */
@@ -6842,7 +6842,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
6842 mutex_lock(&gspca_dev->usb_lock); 6842 mutex_lock(&gspca_dev->usb_lock);
6843 sd->work_thread = NULL; 6843 sd->work_thread = NULL;
6844 } 6844 }
6845 if (!gspca_dev->dev) 6845 if (!gspca_dev->present)
6846 return; 6846 return;
6847 send_unknown(gspca_dev, sd->sensor); 6847 send_unknown(gspca_dev, sd->sensor);
6848} 6848}