aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2015-11-18 12:55:04 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-12-21 18:58:54 -0500
commit06181de14ff09b274b699ee2dd39fe5e37efb419 (patch)
tree66eba4cfa2f1d2b7874a5a3dc084b0657a5aade3
parentb4717ff608c180115ace1d307e7f452e114ca29c (diff)
staging: comedi: rearrange comedi_write() code
Rearrange the code in `comedi_write()` to reduce the amount of indentation. The code never reiterates the `while` loop once `count` has become non-zero, so we can check that in the `while` condition to save an indentation level. (Note that `nbytes` has been checked to be non-zero before entering the loop, so we can remove that check.) Move the code that makes the subdevice "become non-busy" outside the `while` loop, using a new flag variable `become_nonbusy` to decide whether it needs to be done. This simplifies the wait queue handling so there is a single place where the task is removed from the wait queue, and we can remove the `on_wait_queue` flag variable. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/comedi/comedi_fops.c71
1 files changed, 30 insertions, 41 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 7b4af519e17e..c9da6f39b1c6 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2307,7 +2307,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
2307 DECLARE_WAITQUEUE(wait, current); 2307 DECLARE_WAITQUEUE(wait, current);
2308 struct comedi_file *cfp = file->private_data; 2308 struct comedi_file *cfp = file->private_data;
2309 struct comedi_device *dev = cfp->dev; 2309 struct comedi_device *dev = cfp->dev;
2310 bool on_wait_queue = false; 2310 bool become_nonbusy = false;
2311 bool attach_locked; 2311 bool attach_locked;
2312 unsigned int old_detach_count; 2312 unsigned int old_detach_count;
2313 2313
@@ -2342,48 +2342,16 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
2342 } 2342 }
2343 2343
2344 add_wait_queue(&async->wait_head, &wait); 2344 add_wait_queue(&async->wait_head, &wait);
2345 on_wait_queue = true; 2345 while (count == 0 && !retval) {
2346 while (nbytes > 0 && !retval) {
2347 unsigned runflags; 2346 unsigned runflags;
2348 2347
2349 set_current_state(TASK_INTERRUPTIBLE); 2348 set_current_state(TASK_INTERRUPTIBLE);
2350 2349
2351 runflags = comedi_get_subdevice_runflags(s); 2350 runflags = comedi_get_subdevice_runflags(s);
2352 if (!comedi_is_runflags_running(runflags)) { 2351 if (!comedi_is_runflags_running(runflags)) {
2353 if (count == 0) { 2352 if (comedi_is_runflags_in_error(runflags))
2354 struct comedi_subdevice *new_s; 2353 retval = -EPIPE;
2355 2354 become_nonbusy = true;
2356 if (comedi_is_runflags_in_error(runflags))
2357 retval = -EPIPE;
2358 else
2359 retval = 0;
2360 /*
2361 * To avoid deadlock, cannot acquire dev->mutex
2362 * while dev->attach_lock is held. Need to
2363 * remove task from the async wait queue before
2364 * releasing dev->attach_lock, as it might not
2365 * be valid afterwards.
2366 */
2367 remove_wait_queue(&async->wait_head, &wait);
2368 on_wait_queue = false;
2369 up_read(&dev->attach_lock);
2370 attach_locked = false;
2371 mutex_lock(&dev->mutex);
2372 /*
2373 * Become non-busy unless things have changed
2374 * behind our back. Checking dev->detach_count
2375 * is unchanged ought to be sufficient (unless
2376 * there have been 2**32 detaches in the
2377 * meantime!), but check the subdevice pointer
2378 * as well just in case.
2379 */
2380 new_s = comedi_file_write_subdevice(file);
2381 if (dev->attached &&
2382 old_detach_count == dev->detach_count &&
2383 s == new_s && new_s->async == async)
2384 do_become_nonbusy(dev, s);
2385 mutex_unlock(&dev->mutex);
2386 }
2387 break; 2355 break;
2388 } 2356 }
2389 2357
@@ -2433,12 +2401,33 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
2433 nbytes -= n; 2401 nbytes -= n;
2434 2402
2435 buf += n; 2403 buf += n;
2436 break; /* makes device work like a pipe */
2437 } 2404 }
2438out: 2405 remove_wait_queue(&async->wait_head, &wait);
2439 if (on_wait_queue)
2440 remove_wait_queue(&async->wait_head, &wait);
2441 set_current_state(TASK_RUNNING); 2406 set_current_state(TASK_RUNNING);
2407 if (become_nonbusy && count == 0) {
2408 struct comedi_subdevice *new_s;
2409
2410 /*
2411 * To avoid deadlock, cannot acquire dev->mutex
2412 * while dev->attach_lock is held.
2413 */
2414 up_read(&dev->attach_lock);
2415 attach_locked = false;
2416 mutex_lock(&dev->mutex);
2417 /*
2418 * Check device hasn't become detached behind our back.
2419 * Checking dev->detach_count is unchanged ought to be
2420 * sufficient (unless there have been 2**32 detaches in the
2421 * meantime!), but check the subdevice pointer as well just in
2422 * case.
2423 */
2424 new_s = comedi_file_write_subdevice(file);
2425 if (dev->attached && old_detach_count == dev->detach_count &&
2426 s == new_s && new_s->async == async)
2427 do_become_nonbusy(dev, s);
2428 mutex_unlock(&dev->mutex);
2429 }
2430out:
2442 if (attach_locked) 2431 if (attach_locked)
2443 up_read(&dev->attach_lock); 2432 up_read(&dev->attach_lock);
2444 2433