Commit 13e242be authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA update

  - added SNDRV_PCM_IOCTL_HWSYNC ioctl
  - changed behaviour of read/write/poll functions
    - prefer waiting than return an error code
  - removed snd_seq_sleep_timeout_in_lock and snd_seq_sleep_in_lock helpers
parent a69156f1
...@@ -129,7 +129,7 @@ enum { ...@@ -129,7 +129,7 @@ enum {
* * * *
*****************************************************************************/ *****************************************************************************/
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2) #define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 3)
typedef unsigned long sndrv_pcm_uframes_t; typedef unsigned long sndrv_pcm_uframes_t;
typedef long sndrv_pcm_sframes_t; typedef long sndrv_pcm_sframes_t;
...@@ -423,6 +423,7 @@ enum { ...@@ -423,6 +423,7 @@ enum {
SNDRV_PCM_IOCTL_SW_PARAMS = _IOWR('A', 0x13, struct sndrv_pcm_sw_params), SNDRV_PCM_IOCTL_SW_PARAMS = _IOWR('A', 0x13, struct sndrv_pcm_sw_params),
SNDRV_PCM_IOCTL_STATUS = _IOR('A', 0x20, struct sndrv_pcm_status), SNDRV_PCM_IOCTL_STATUS = _IOR('A', 0x20, struct sndrv_pcm_status),
SNDRV_PCM_IOCTL_DELAY = _IOR('A', 0x21, sndrv_pcm_sframes_t), SNDRV_PCM_IOCTL_DELAY = _IOR('A', 0x21, sndrv_pcm_sframes_t),
SNDRV_PCM_IOCTL_HWSYNC = _IO('A', 0x22),
SNDRV_PCM_IOCTL_CHANNEL_INFO = _IOR('A', 0x32, struct sndrv_pcm_channel_info), SNDRV_PCM_IOCTL_CHANNEL_INFO = _IOR('A', 0x32, struct sndrv_pcm_channel_info),
SNDRV_PCM_IOCTL_PREPARE = _IO('A', 0x40), SNDRV_PCM_IOCTL_PREPARE = _IO('A', 0x40),
SNDRV_PCM_IOCTL_RESET = _IO('A', 0x41), SNDRV_PCM_IOCTL_RESET = _IO('A', 0x41),
......
...@@ -1854,16 +1854,11 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, ...@@ -1854,16 +1854,11 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING) if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
snd_pcm_update_hw_ptr(substream); snd_pcm_update_hw_ptr(substream);
avail = snd_pcm_playback_avail(runtime); avail = snd_pcm_playback_avail(runtime);
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED || if (((avail < runtime->control->avail_min && size > avail) ||
runtime->status->state == SNDRV_PCM_STATE_PREPARED) {
if (avail < runtime->xfer_align) {
err = -EPIPE;
goto _end_unlock;
}
} else if (((avail < runtime->control->avail_min && size > avail) ||
(size >= runtime->xfer_align && avail < runtime->xfer_align))) { (size >= runtime->xfer_align && avail < runtime->xfer_align))) {
wait_queue_t wait; wait_queue_t wait;
enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state; enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state;
if (nonblock) { if (nonblock) {
err = -EAGAIN; err = -EAGAIN;
goto _end_unlock; goto _end_unlock;
...@@ -1880,9 +1875,12 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, ...@@ -1880,9 +1875,12 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
spin_unlock_irq(&runtime->lock); spin_unlock_irq(&runtime->lock);
if (schedule_timeout(10 * HZ) == 0) { if (schedule_timeout(10 * HZ) == 0) {
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
if (runtime->status->state != SNDRV_PCM_STATE_PREPARED &&
runtime->status->state != SNDRV_PCM_STATE_PAUSED) {
state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED; state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED;
break; break;
} }
}
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
...@@ -1928,10 +1926,6 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, ...@@ -1928,10 +1926,6 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
if (frames > cont) if (frames > cont)
frames = cont; frames = cont;
if (frames == 0 && runtime->status->state == SNDRV_PCM_STATE_PAUSED) {
err = -EPIPE;
goto _end_unlock;
}
snd_assert(frames != 0, snd_assert(frames != 0,
spin_unlock_irq(&runtime->lock); spin_unlock_irq(&runtime->lock);
return -EINVAL); return -EINVAL);
...@@ -2147,21 +2141,16 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void ...@@ -2147,21 +2141,16 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void
if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING) if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
snd_pcm_update_hw_ptr(substream); snd_pcm_update_hw_ptr(substream);
avail = snd_pcm_capture_avail(runtime); avail = snd_pcm_capture_avail(runtime);
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) { if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
if (avail < runtime->xfer_align) { if (avail < runtime->xfer_align) {
err = -EPIPE; err = -EPIPE;
goto _end_unlock; goto _end_unlock;
} }
} else if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
if (avail < runtime->xfer_align) {
runtime->status->state = SNDRV_PCM_STATE_SETUP;
err = -EPIPE;
goto _end_unlock;
}
} else if ((avail < runtime->control->avail_min && size > avail) || } else if ((avail < runtime->control->avail_min && size > avail) ||
(size >= runtime->xfer_align && avail < runtime->xfer_align)) { (size >= runtime->xfer_align && avail < runtime->xfer_align)) {
wait_queue_t wait; wait_queue_t wait;
enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state; enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state;
if (nonblock) { if (nonblock) {
err = -EAGAIN; err = -EAGAIN;
goto _end_unlock; goto _end_unlock;
...@@ -2178,9 +2167,12 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void ...@@ -2178,9 +2167,12 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void
spin_unlock_irq(&runtime->lock); spin_unlock_irq(&runtime->lock);
if (schedule_timeout(10 * HZ) == 0) { if (schedule_timeout(10 * HZ) == 0) {
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
if (runtime->status->state != SNDRV_PCM_STATE_PREPARED &&
runtime->status->state != SNDRV_PCM_STATE_PAUSED) {
state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED; state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED;
break; break;
} }
}
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
......
...@@ -1962,34 +1962,29 @@ snd_pcm_sframes_t snd_pcm_capture_rewind(snd_pcm_substream_t *substream, snd_pcm ...@@ -1962,34 +1962,29 @@ snd_pcm_sframes_t snd_pcm_capture_rewind(snd_pcm_substream_t *substream, snd_pcm
return ret; return ret;
} }
static int snd_pcm_playback_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t *res) static int snd_pcm_hwsync(snd_pcm_substream_t *substream)
{ {
snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_runtime_t *runtime = substream->runtime;
int err = 0; int err;
snd_pcm_sframes_t n;
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_DRAINING: case SNDRV_PCM_STATE_DRAINING:
if (snd_pcm_update_hw_ptr(substream) >= 0) { if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
n = snd_pcm_playback_hw_avail(runtime); goto __badfd;
if (put_user(n, res)) case SNDRV_PCM_STATE_RUNNING:
err = -EFAULT; if ((err = snd_pcm_update_hw_ptr(substream)) < 0)
break;
} else {
err = SNDRV_PCM_STATE_RUNNING ? -EPIPE : -EBADFD;
}
break; break;
/* Fall through */
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_SUSPENDED: case SNDRV_PCM_STATE_SUSPENDED:
if (runtime->status->suspended_state == SNDRV_PCM_STATE_RUNNING) { err = 0;
n = snd_pcm_playback_hw_avail(runtime); break;
if (put_user(n, res)) case SNDRV_PCM_STATE_XRUN:
err = -EFAULT; err = -EPIPE;
} else {
err = -EBADFD;
}
break; break;
default: default:
__badfd:
err = -EBADFD; err = -EBADFD;
break; break;
} }
...@@ -1997,34 +1992,36 @@ static int snd_pcm_playback_delay(snd_pcm_substream_t *substream, snd_pcm_sframe ...@@ -1997,34 +1992,36 @@ static int snd_pcm_playback_delay(snd_pcm_substream_t *substream, snd_pcm_sframe
return err; return err;
} }
static int snd_pcm_capture_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t *res) static int snd_pcm_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t *res)
{ {
snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_runtime_t *runtime = substream->runtime;
int err = 0; int err;
snd_pcm_sframes_t n; snd_pcm_sframes_t n;
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_DRAINING:
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
goto __badfd;
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
if (snd_pcm_update_hw_ptr(substream) >= 0) { if ((err = snd_pcm_update_hw_ptr(substream)) < 0)
n = snd_pcm_capture_avail(runtime);
if (put_user(n, res))
err = -EFAULT;
break; break;
}
/* Fall through */ /* Fall through */
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_PREPARED:
err = -EPIPE;
break;
case SNDRV_PCM_STATE_SUSPENDED: case SNDRV_PCM_STATE_SUSPENDED:
if (runtime->status->suspended_state == SNDRV_PCM_STATE_RUNNING) { err = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
n = snd_pcm_playback_hw_avail(runtime);
else
n = snd_pcm_capture_avail(runtime); n = snd_pcm_capture_avail(runtime);
if (put_user(n, res)) if (put_user(n, res))
err = -EFAULT; err = -EFAULT;
} else { break;
err = -EBADFD; case SNDRV_PCM_STATE_XRUN:
} err = -EPIPE;
break; break;
default: default:
__badfd:
err = -EBADFD; err = -EBADFD;
break; break;
} }
...@@ -2079,6 +2076,10 @@ static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream, ...@@ -2079,6 +2076,10 @@ static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream,
return snd_pcm_resume(substream); return snd_pcm_resume(substream);
case SNDRV_PCM_IOCTL_XRUN: case SNDRV_PCM_IOCTL_XRUN:
return snd_pcm_xrun(substream); return snd_pcm_xrun(substream);
case SNDRV_PCM_IOCTL_HWSYNC:
return snd_pcm_hwsync(substream);
case SNDRV_PCM_IOCTL_DELAY:
return snd_pcm_delay(substream, (snd_pcm_sframes_t *) arg);
case SNDRV_PCM_IOCTL_HW_REFINE_OLD: case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
return snd_pcm_hw_refine_old_user(substream, (struct sndrv_pcm_hw_params_old *) arg); return snd_pcm_hw_refine_old_user(substream, (struct sndrv_pcm_hw_params_old *) arg);
case SNDRV_PCM_IOCTL_HW_PARAMS_OLD: case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
...@@ -2159,8 +2160,6 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream, ...@@ -2159,8 +2160,6 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
return snd_pcm_playback_drain(substream); return snd_pcm_playback_drain(substream);
case SNDRV_PCM_IOCTL_DROP: case SNDRV_PCM_IOCTL_DROP:
return snd_pcm_playback_drop(substream); return snd_pcm_playback_drop(substream);
case SNDRV_PCM_IOCTL_DELAY:
return snd_pcm_playback_delay(substream, (snd_pcm_sframes_t*) arg);
} }
return snd_pcm_common_ioctl1(substream, cmd, arg); return snd_pcm_common_ioctl1(substream, cmd, arg);
} }
...@@ -2228,8 +2227,6 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream, ...@@ -2228,8 +2227,6 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
return snd_pcm_capture_drain(substream); return snd_pcm_capture_drain(substream);
case SNDRV_PCM_IOCTL_DROP: case SNDRV_PCM_IOCTL_DROP:
return snd_pcm_capture_drop(substream); return snd_pcm_capture_drop(substream);
case SNDRV_PCM_IOCTL_DELAY:
return snd_pcm_capture_delay(substream, (snd_pcm_sframes_t*) arg);
} }
return snd_pcm_common_ioctl1(substream, cmd, arg); return snd_pcm_common_ioctl1(substream, cmd, arg);
} }
...@@ -2326,7 +2323,9 @@ static ssize_t snd_pcm_write(struct file *file, const char *buf, size_t count, l ...@@ -2326,7 +2323,9 @@ static ssize_t snd_pcm_write(struct file *file, const char *buf, size_t count, l
snd_pcm_runtime_t *runtime; snd_pcm_runtime_t *runtime;
snd_pcm_sframes_t result; snd_pcm_sframes_t result;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
up(&file->f_dentry->d_inode->i_sem); up(&file->f_dentry->d_inode->i_sem);
#endif
pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, result = -ENXIO; goto end); pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, result = -ENXIO; goto end);
substream = pcm_file->substream; substream = pcm_file->substream;
snd_assert(substream != NULL, result = -ENXIO; goto end); snd_assert(substream != NULL, result = -ENXIO; goto end);
...@@ -2344,7 +2343,9 @@ static ssize_t snd_pcm_write(struct file *file, const char *buf, size_t count, l ...@@ -2344,7 +2343,9 @@ static ssize_t snd_pcm_write(struct file *file, const char *buf, size_t count, l
if (result > 0) if (result > 0)
result = frames_to_bytes(runtime, result); result = frames_to_bytes(runtime, result);
end: end:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
down(&file->f_dentry->d_inode->i_sem); down(&file->f_dentry->d_inode->i_sem);
#endif
return result; return result;
} }
...@@ -2449,6 +2450,8 @@ unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait) ...@@ -2449,6 +2450,8 @@ unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
avail = snd_pcm_playback_avail(runtime); avail = snd_pcm_playback_avail(runtime);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_PAUSED:
if (avail >= runtime->control->avail_min) { if (avail >= runtime->control->avail_min) {
mask = POLLOUT | POLLWRNORM; mask = POLLOUT | POLLWRNORM;
break; break;
...@@ -2457,12 +2460,6 @@ unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait) ...@@ -2457,12 +2460,6 @@ unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
case SNDRV_PCM_STATE_DRAINING: case SNDRV_PCM_STATE_DRAINING:
mask = 0; mask = 0;
break; break;
case SNDRV_PCM_STATE_PREPARED:
if (avail > 0) {
mask = POLLOUT | POLLWRNORM;
break;
}
/* Fall through */
default: default:
mask = POLLOUT | POLLWRNORM | POLLERR; mask = POLLOUT | POLLWRNORM | POLLERR;
break; break;
...@@ -2491,6 +2488,8 @@ unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait) ...@@ -2491,6 +2488,8 @@ unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
avail = snd_pcm_capture_avail(runtime); avail = snd_pcm_capture_avail(runtime);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_PAUSED:
if (avail >= runtime->control->avail_min) { if (avail >= runtime->control->avail_min) {
mask = POLLIN | POLLRDNORM; mask = POLLIN | POLLRDNORM;
break; break;
......
...@@ -159,9 +159,10 @@ snd_seq_oss_readq_pick(seq_oss_readq_t *q, int blocking, unsigned long *rflags) ...@@ -159,9 +159,10 @@ snd_seq_oss_readq_pick(seq_oss_readq_t *q, int blocking, unsigned long *rflags)
spin_lock_irqsave(&q->lock, *rflags); spin_lock_irqsave(&q->lock, *rflags);
if (q->qlen == 0) { if (q->qlen == 0) {
if (blocking) { if (blocking) {
snd_seq_sleep_timeout_in_lock(&q->midi_sleep, spin_unlock(&q->lock);
&q->lock, interruptible_sleep_on_timeout(&q->midi_sleep,
q->pre_event_timeout); q->pre_event_timeout);
spin_lock(&q->lock);
} }
if (q->qlen == 0) { if (q->qlen == 0) {
spin_unlock_irqrestore(&q->lock, *rflags); spin_unlock_irqrestore(&q->lock, *rflags);
......
...@@ -122,7 +122,9 @@ snd_seq_oss_writeq_sync(seq_oss_writeq_t *q) ...@@ -122,7 +122,9 @@ snd_seq_oss_writeq_sync(seq_oss_writeq_t *q)
} }
/* wait for echo event */ /* wait for echo event */
snd_seq_sleep_timeout_in_lock(&q->sync_sleep, &q->sync_lock, HZ); spin_unlock(&q->sync_lock);
interruptible_sleep_on_timeout(&q->sync_sleep, HZ);
spin_lock(&q->sync_lock);
if (signal_pending(current)) { if (signal_pending(current)) {
/* interrupted - return 0 to finish sync */ /* interrupted - return 0 to finish sync */
q->sync_event_put = 0; q->sync_event_put = 0;
......
...@@ -135,7 +135,7 @@ EXPORT_SYMBOL(snd_seq_event_port_attach); ...@@ -135,7 +135,7 @@ EXPORT_SYMBOL(snd_seq_event_port_attach);
EXPORT_SYMBOL(snd_seq_event_port_detach); EXPORT_SYMBOL(snd_seq_event_port_detach);
/* seq_lock.c */ /* seq_lock.c */
#if defined(__SMP__) || defined(CONFIG_SND_DEBUG) #if defined(__SMP__) || defined(CONFIG_SND_DEBUG)
EXPORT_SYMBOL(snd_seq_sleep_in_lock); /*EXPORT_SYMBOL(snd_seq_sleep_in_lock);*/
EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock); /*EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock);*/
EXPORT_SYMBOL(snd_use_lock_sync_helper); EXPORT_SYMBOL(snd_use_lock_sync_helper);
#endif #endif
...@@ -182,7 +182,9 @@ int snd_seq_fifo_cell_out(fifo_t *f, snd_seq_event_cell_t **cellp, int nonblock) ...@@ -182,7 +182,9 @@ int snd_seq_fifo_cell_out(fifo_t *f, snd_seq_event_cell_t **cellp, int nonblock)
spin_unlock_irqrestore(&f->lock, flags); spin_unlock_irqrestore(&f->lock, flags);
return -EAGAIN; return -EAGAIN;
} }
snd_seq_sleep_in_lock(&f->input_sleep, &f->lock); spin_unlock(&f->lock);
interruptible_sleep_on(&f->input_sleep);
spin_lock(&f->lock);
if (signal_pending(current)) { if (signal_pending(current)) {
spin_unlock_irqrestore(&f->lock, flags); spin_unlock_irqrestore(&f->lock, flags);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#if defined(__SMP__) || defined(CONFIG_SND_DEBUG) #if defined(__SMP__) || defined(CONFIG_SND_DEBUG)
#if 0 /* NOT USED */
/* (interruptible) sleep_on during the specified spinlock */ /* (interruptible) sleep_on during the specified spinlock */
void snd_seq_sleep_in_lock(wait_queue_head_t *p, spinlock_t *lock) void snd_seq_sleep_in_lock(wait_queue_head_t *p, spinlock_t *lock)
{ {
...@@ -60,6 +61,7 @@ long snd_seq_sleep_timeout_in_lock(wait_queue_head_t *p, spinlock_t *lock, long ...@@ -60,6 +61,7 @@ long snd_seq_sleep_timeout_in_lock(wait_queue_head_t *p, spinlock_t *lock, long
return timeout; return timeout;
} }
#endif /* NOT USED */
/* wait until all locks are released */ /* wait until all locks are released */
void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
......
...@@ -20,12 +20,6 @@ typedef atomic_t snd_use_lock_t; ...@@ -20,12 +20,6 @@ typedef atomic_t snd_use_lock_t;
void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line); void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line);
#define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__) #define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__)
/* (interruptible) sleep_on during the specified spinlock */
void snd_seq_sleep_in_lock(wait_queue_head_t *p, spinlock_t *lock);
/* (interruptible) sleep_on with timeout during the specified spinlock */
long snd_seq_sleep_timeout_in_lock(wait_queue_head_t *p, spinlock_t *lock, long timeout);
#else /* SMP || CONFIG_SND_DEBUG */ #else /* SMP || CONFIG_SND_DEBUG */
typedef spinlock_t snd_use_lock_t; /* dummy */ typedef spinlock_t snd_use_lock_t; /* dummy */
...@@ -34,9 +28,6 @@ typedef spinlock_t snd_use_lock_t; /* dummy */ ...@@ -34,9 +28,6 @@ typedef spinlock_t snd_use_lock_t; /* dummy */
#define snd_use_lock_free(lockp) /**/ #define snd_use_lock_free(lockp) /**/
#define snd_use_lock_sync(lockp) /**/ #define snd_use_lock_sync(lockp) /**/
#define snd_seq_sleep_in_lock(p,lock) interruptible_sleep_on(p)
#define snd_seq_sleep_timeout_in_lock(p,lock,timeout) interruptible_sleep_on_timeout(p,timeout)
#endif /* SMP || CONFIG_SND_DEBUG */ #endif /* SMP || CONFIG_SND_DEBUG */
#endif /* __SND_SEQ_LOCK_H */ #endif /* __SND_SEQ_LOCK_H */
...@@ -233,17 +233,21 @@ int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock, ...@@ -233,17 +233,21 @@ int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock,
goto __error; goto __error;
} }
while (pool->free == NULL && ! nonblock && ! pool->closing) { while (pool->free == NULL && ! nonblock && ! pool->closing) {
spin_unlock(&pool->lock);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
/* change semaphore to allow other clients /* change semaphore to allow other clients
to access device file */ to access device file */
if (file) if (file)
up(&semaphore_of(file)); up(&semaphore_of(file));
#endif
snd_seq_sleep_in_lock(&pool->output_sleep, &pool->lock); interruptible_sleep_on(&pool->output_sleep);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
/* restore semaphore again */ /* restore semaphore again */
if (file) if (file)
down(&semaphore_of(file)); down(&semaphore_of(file));
#endif
spin_lock(&pool->lock);
/* interrupted? */ /* interrupted? */
if (signal_pending(current)) { if (signal_pending(current)) {
err = -ERESTARTSYS; err = -ERESTARTSYS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment