/* Because this function is inlined, the 'state' parameter will be constant, and thus optimised away by the compiler. Likewise the 'timeout' parameter for the cases without timeouts.  */
static int __sched __down_common(struct semaphore *sem, long state, long timeout)
/* Because this function is inlined, the 'state' parameter will be constant, and thus optimised away by the compiler. Likewise the 'timeout' parameter for the cases without timeouts.  */
static int __sched __down_common(struct semaphore *sem, long state, long timeout)
{
	struct task_struct *task = current;
	struct semaphore_waiter waiter;
	list_add_tail(&waiter.list, &sem->wait_list);
	waiter.task = task;
	waiter.up = 0;
	for (;;) {
		if (signal_pending_state(state, task))
			goto interrupted;
		if (timeout <= 0)
			goto timed_out;
		__set_task_state(task, state);
		spin_unlock_irq(&sem->lock);
		timeout = schedule_timeout(timeout);
		spin_lock_irq(&sem->lock);
		if (waiter.up)
			return 0;
	}
 timed_out:
	list_del(&waiter.list);
	return -ETIME;
 interrupted:
	list_del(&waiter.list);
	return -EINTR;
}