-static int devstate_read_lock_timeout(struct taskdev *dev, long devstate,
- int timeout)
-{
- DECLARE_WAITQUEUE(wait, current);
- long current_state = current->state;
- int ret = 0;
-
- down_read(&dev->state_sem);
- if (dev->state & devstate)
- return 0;
-
- add_wait_queue(&dev->state_wait_q, &wait);
- do {
- set_current_state(TASK_INTERRUPTIBLE);
- up_read(&dev->state_sem);
- if (timeout) {
- if ((timeout = schedule_timeout(timeout)) == 0) {
- /* timeout */
- down_read(&dev->state_sem);
- break;
- }
- } else
- schedule();
- if (signal_pending(current)) {
- ret = -EINTR;
- break;
- }
- down_read(&dev->state_sem);
- } while (!(dev->state & devstate));
- remove_wait_queue(&dev->state_wait_q, &wait);
- set_current_state(current_state);
- return ret;
-}
-
-static int devstate_read_lock_and_test(struct taskdev *dev, long devstate)
-{
- down_read(&dev->state_sem);
- if (dev->state & devstate)
- return 1; /* success */
- /* failure */
- up_read(&dev->state_sem);
- return 0;
-}
-
-static int devstate_write_lock_timeout(struct taskdev *dev, long devstate,
- int timeout)
-{
- DECLARE_WAITQUEUE(wait, current);
- long current_state = current->state;
- int ret = 0;
-
- down_write(&dev->state_sem);
- if (dev->state & devstate)
- return 0;
-
- add_wait_queue(&dev->state_wait_q, &wait);
- do {
- set_current_state(TASK_INTERRUPTIBLE);
- up_write(&dev->state_sem);
- if (timeout) {
- if ((timeout = schedule_timeout(timeout)) == 0) {
- /* timeout */
- down_write(&dev->state_sem);
- break;
- }
- } else
- schedule();
- if (signal_pending(current)) {
- ret = -EINTR;
- break;
- }
- down_write(&dev->state_sem);
- } while (!(dev->state & devstate));
- remove_wait_queue(&dev->state_wait_q, &wait);
- set_current_state(current_state);
- return ret;
-}
-
-static int devstate_write_lock_and_test(struct taskdev *dev, long devstate)
-{
- down_write(&dev->state_sem);
- if (dev->state & devstate) /* success */
- return 1;
-
- /* failure */
- up_write(&dev->state_sem);
- return -1;
-}
+#define BUILD_DEVSTATE_LOCK_TIMEOUT(rw) \
+static int devstate_##rw##_lock_timeout(struct taskdev *dev, long devstate, \
+ int timeout) \
+{ \
+ DEFINE_WAIT(wait); \
+ down_##rw(&dev->state_sem); \
+ while (!(dev->state & devstate)) { \
+ up_##rw(&dev->state_sem); \
+ prepare_to_wait(&dev->state_wait_q, &wait, TASK_INTERRUPTIBLE); \
+ if (!timeout) \
+ timeout = MAX_SCHEDULE_TIMEOUT; \
+ timeout = schedule_timeout(timeout); \
+ finish_wait(&dev->state_wait_q, &wait); \
+ if (timeout == 0) \
+ return -ETIME; \
+ if (signal_pending(current)) \
+ return -EINTR; \
+ down_##rw(&dev->state_sem); \
+ } \
+ return 0; \
+}
+BUILD_DEVSTATE_LOCK_TIMEOUT(read)
+BUILD_DEVSTATE_LOCK_TIMEOUT(write)
+
+#define BUILD_DEVSTATE_LOCK_AND_TEST(rw) \
+static int devstate_##rw##_lock_and_test(struct taskdev *dev, long devstate) \
+{ \
+ down_##rw(&dev->state_sem); \
+ if (dev->state & devstate) \
+ return 1; /* success */ \
+ /* failure */ \
+ up_##rw(&dev->state_sem); \
+ return 0; \
+}
+BUILD_DEVSTATE_LOCK_AND_TEST(read)
+BUILD_DEVSTATE_LOCK_AND_TEST(write)