aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usx2y/us122l.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usx2y/us122l.c')
-rw-r--r--sound/usb/usx2y/us122l.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 6ef68e42138e..084e6fc8d5bf 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -273,29 +273,26 @@ static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
273 struct file *file, poll_table *wait) 273 struct file *file, poll_table *wait)
274{ 274{
275 struct us122l *us122l = hw->private_data; 275 struct us122l *us122l = hw->private_data;
276 struct usb_stream *s = us122l->sk.s;
277 unsigned *polled; 276 unsigned *polled;
278 unsigned int mask; 277 unsigned int mask;
279 278
280 poll_wait(file, &us122l->sk.sleep, wait); 279 poll_wait(file, &us122l->sk.sleep, wait);
281 280
282 switch (s->state) { 281 mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
283 case usb_stream_ready: 282 if (mutex_trylock(&us122l->mutex)) {
284 if (us122l->first == file) 283 struct usb_stream *s = us122l->sk.s;
285 polled = &s->periods_polled; 284 if (s && s->state == usb_stream_ready) {
286 else 285 if (us122l->first == file)
287 polled = &us122l->second_periods_polled; 286 polled = &s->periods_polled;
288 if (*polled != s->periods_done) { 287 else
289 *polled = s->periods_done; 288 polled = &us122l->second_periods_polled;
290 mask = POLLIN | POLLOUT | POLLWRNORM; 289 if (*polled != s->periods_done) {
291 break; 290 *polled = s->periods_done;
291 mask = POLLIN | POLLOUT | POLLWRNORM;
292 } else
293 mask = 0;
292 } 294 }
293 /* Fall through */ 295 mutex_unlock(&us122l->mutex);
294 mask = 0;
295 break;
296 default:
297 mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
298 break;
299 } 296 }
300 return mask; 297 return mask;
301} 298}
@@ -381,6 +378,7 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
381{ 378{
382 struct usb_stream_config *cfg; 379 struct usb_stream_config *cfg;
383 struct us122l *us122l = hw->private_data; 380 struct us122l *us122l = hw->private_data;
381 struct usb_stream *s;
384 unsigned min_period_frames; 382 unsigned min_period_frames;
385 int err = 0; 383 int err = 0;
386 bool high_speed; 384 bool high_speed;
@@ -426,18 +424,18 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
426 snd_power_wait(hw->card, SNDRV_CTL_POWER_D0); 424 snd_power_wait(hw->card, SNDRV_CTL_POWER_D0);
427 425
428 mutex_lock(&us122l->mutex); 426 mutex_lock(&us122l->mutex);
427 s = us122l->sk.s;
429 if (!us122l->master) 428 if (!us122l->master)
430 us122l->master = file; 429 us122l->master = file;
431 else if (us122l->master != file) { 430 else if (us122l->master != file) {
432 if (memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg))) { 431 if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg))) {
433 err = -EIO; 432 err = -EIO;
434 goto unlock; 433 goto unlock;
435 } 434 }
436 us122l->slave = file; 435 us122l->slave = file;
437 } 436 }
438 if (!us122l->sk.s || 437 if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg)) ||
439 memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg)) || 438 s->state == usb_stream_xrun) {
440 us122l->sk.s->state == usb_stream_xrun) {
441 us122l_stop(us122l); 439 us122l_stop(us122l);
442 if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames)) 440 if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames))
443 err = -EIO; 441 err = -EIO;
@@ -448,6 +446,7 @@ unlock:
448 mutex_unlock(&us122l->mutex); 446 mutex_unlock(&us122l->mutex);
449free: 447free:
450 kfree(cfg); 448 kfree(cfg);
449 wake_up_all(&us122l->sk.sleep);
451 return err; 450 return err;
452} 451}
453 452