aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-11-01 05:11:07 -0500
committerTakashi Iwai <tiwai@suse.de>2009-11-01 05:11:07 -0500
commite87a3dd33eab30b4db539500064a9584867e4f2c (patch)
tree2f7ad16e46ae30518ff63bb5391b63f7f7cc74dd /sound/core
parentb14f5de731ae657d498d18d713c6431bfbeefb4b (diff)
parent3d00941371a765779c4e3509214c7e5793cce1fe (diff)
Merge branch 'fix/misc' into topic/misc
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/pcm.c5
-rw-r--r--sound/core/pcm_native.c81
2 files changed, 27 insertions, 59 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 0c1440121c22..c69c60b2a48a 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -953,11 +953,12 @@ static int snd_pcm_dev_register(struct snd_device *device)
953 struct snd_pcm_substream *substream; 953 struct snd_pcm_substream *substream;
954 struct snd_pcm_notify *notify; 954 struct snd_pcm_notify *notify;
955 char str[16]; 955 char str[16];
956 struct snd_pcm *pcm = device->device_data; 956 struct snd_pcm *pcm;
957 struct device *dev; 957 struct device *dev;
958 958
959 if (snd_BUG_ON(!pcm || !device)) 959 if (snd_BUG_ON(!device || !device->device_data))
960 return -ENXIO; 960 return -ENXIO;
961 pcm = device->device_data;
961 mutex_lock(&register_mutex); 962 mutex_lock(&register_mutex);
962 err = snd_pcm_add(pcm); 963 err = snd_pcm_add(pcm);
963 if (err) { 964 if (err) {
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 59e5fbe6af51..ab73edf2c89a 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1387,11 +1387,6 @@ static struct action_ops snd_pcm_action_drain_init = {
1387 .post_action = snd_pcm_post_drain_init 1387 .post_action = snd_pcm_post_drain_init
1388}; 1388};
1389 1389
1390struct drain_rec {
1391 struct snd_pcm_substream *substream;
1392 wait_queue_t wait;
1393};
1394
1395static int snd_pcm_drop(struct snd_pcm_substream *substream); 1390static int snd_pcm_drop(struct snd_pcm_substream *substream);
1396 1391
1397/* 1392/*
@@ -1407,10 +1402,9 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
1407 struct snd_card *card; 1402 struct snd_card *card;
1408 struct snd_pcm_runtime *runtime; 1403 struct snd_pcm_runtime *runtime;
1409 struct snd_pcm_substream *s; 1404 struct snd_pcm_substream *s;
1405 wait_queue_t wait;
1410 int result = 0; 1406 int result = 0;
1411 int i, num_drecs;
1412 int nonblock = 0; 1407 int nonblock = 0;
1413 struct drain_rec *drec, drec_tmp, *d;
1414 1408
1415 card = substream->pcm->card; 1409 card = substream->pcm->card;
1416 runtime = substream->runtime; 1410 runtime = substream->runtime;
@@ -1433,38 +1427,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
1433 } else if (substream->f_flags & O_NONBLOCK) 1427 } else if (substream->f_flags & O_NONBLOCK)
1434 nonblock = 1; 1428 nonblock = 1;
1435 1429
1436 if (nonblock)
1437 goto lock; /* no need to allocate waitqueues */
1438
1439 /* allocate temporary record for drain sync */
1440 down_read(&snd_pcm_link_rwsem); 1430 down_read(&snd_pcm_link_rwsem);
1441 if (snd_pcm_stream_linked(substream)) {
1442 drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL);
1443 if (! drec) {
1444 up_read(&snd_pcm_link_rwsem);
1445 snd_power_unlock(card);
1446 return -ENOMEM;
1447 }
1448 } else
1449 drec = &drec_tmp;
1450
1451 /* count only playback streams */
1452 num_drecs = 0;
1453 snd_pcm_group_for_each_entry(s, substream) {
1454 runtime = s->runtime;
1455 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1456 d = &drec[num_drecs++];
1457 d->substream = s;
1458 init_waitqueue_entry(&d->wait, current);
1459 add_wait_queue(&runtime->sleep, &d->wait);
1460 }
1461 }
1462 up_read(&snd_pcm_link_rwsem);
1463
1464 lock:
1465 snd_pcm_stream_lock_irq(substream); 1431 snd_pcm_stream_lock_irq(substream);
1466 /* resume pause */ 1432 /* resume pause */
1467 if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED) 1433 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
1468 snd_pcm_pause(substream, 0); 1434 snd_pcm_pause(substream, 0);
1469 1435
1470 /* pre-start/stop - all running streams are changed to DRAINING state */ 1436 /* pre-start/stop - all running streams are changed to DRAINING state */
@@ -1479,25 +1445,35 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
1479 1445
1480 for (;;) { 1446 for (;;) {
1481 long tout; 1447 long tout;
1448 struct snd_pcm_runtime *to_check;
1482 if (signal_pending(current)) { 1449 if (signal_pending(current)) {
1483 result = -ERESTARTSYS; 1450 result = -ERESTARTSYS;
1484 break; 1451 break;
1485 } 1452 }
1486 /* all finished? */ 1453 /* find a substream to drain */
1487 for (i = 0; i < num_drecs; i++) { 1454 to_check = NULL;
1488 runtime = drec[i].substream->runtime; 1455 snd_pcm_group_for_each_entry(s, substream) {
1489 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) 1456 if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
1457 continue;
1458 runtime = s->runtime;
1459 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
1460 to_check = runtime;
1490 break; 1461 break;
1462 }
1491 } 1463 }
1492 if (i == num_drecs) 1464 if (!to_check)
1493 break; /* yes, all drained */ 1465 break; /* all drained */
1494 1466 init_waitqueue_entry(&wait, current);
1467 add_wait_queue(&to_check->sleep, &wait);
1495 set_current_state(TASK_INTERRUPTIBLE); 1468 set_current_state(TASK_INTERRUPTIBLE);
1496 snd_pcm_stream_unlock_irq(substream); 1469 snd_pcm_stream_unlock_irq(substream);
1470 up_read(&snd_pcm_link_rwsem);
1497 snd_power_unlock(card); 1471 snd_power_unlock(card);
1498 tout = schedule_timeout(10 * HZ); 1472 tout = schedule_timeout(10 * HZ);
1499 snd_power_lock(card); 1473 snd_power_lock(card);
1474 down_read(&snd_pcm_link_rwsem);
1500 snd_pcm_stream_lock_irq(substream); 1475 snd_pcm_stream_lock_irq(substream);
1476 remove_wait_queue(&to_check->sleep, &wait);
1501 if (tout == 0) { 1477 if (tout == 0) {
1502 if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) 1478 if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
1503 result = -ESTRPIPE; 1479 result = -ESTRPIPE;
@@ -1512,16 +1488,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
1512 1488
1513 unlock: 1489 unlock:
1514 snd_pcm_stream_unlock_irq(substream); 1490 snd_pcm_stream_unlock_irq(substream);
1515 1491 up_read(&snd_pcm_link_rwsem);
1516 if (!nonblock) {
1517 for (i = 0; i < num_drecs; i++) {
1518 d = &drec[i];
1519 runtime = d->substream->runtime;
1520 remove_wait_queue(&runtime->sleep, &d->wait);
1521 }
1522 if (drec != &drec_tmp)
1523 kfree(drec);
1524 }
1525 snd_power_unlock(card); 1492 snd_power_unlock(card);
1526 1493
1527 return result; 1494 return result;
@@ -3018,7 +2985,7 @@ static int snd_pcm_mmap_status_fault(struct vm_area_struct *area,
3018 return 0; 2985 return 0;
3019} 2986}
3020 2987
3021static struct vm_operations_struct snd_pcm_vm_ops_status = 2988static const struct vm_operations_struct snd_pcm_vm_ops_status =
3022{ 2989{
3023 .fault = snd_pcm_mmap_status_fault, 2990 .fault = snd_pcm_mmap_status_fault,
3024}; 2991};
@@ -3057,7 +3024,7 @@ static int snd_pcm_mmap_control_fault(struct vm_area_struct *area,
3057 return 0; 3024 return 0;
3058} 3025}
3059 3026
3060static struct vm_operations_struct snd_pcm_vm_ops_control = 3027static const struct vm_operations_struct snd_pcm_vm_ops_control =
3061{ 3028{
3062 .fault = snd_pcm_mmap_control_fault, 3029 .fault = snd_pcm_mmap_control_fault,
3063}; 3030};
@@ -3127,7 +3094,7 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3127 return 0; 3094 return 0;
3128} 3095}
3129 3096
3130static struct vm_operations_struct snd_pcm_vm_ops_data = 3097static const struct vm_operations_struct snd_pcm_vm_ops_data =
3131{ 3098{
3132 .open = snd_pcm_mmap_data_open, 3099 .open = snd_pcm_mmap_data_open,
3133 .close = snd_pcm_mmap_data_close, 3100 .close = snd_pcm_mmap_data_close,
@@ -3151,7 +3118,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3151 * mmap the DMA buffer on I/O memory area 3118 * mmap the DMA buffer on I/O memory area
3152 */ 3119 */
3153#if SNDRV_PCM_INFO_MMAP_IOMEM 3120#if SNDRV_PCM_INFO_MMAP_IOMEM
3154static struct vm_operations_struct snd_pcm_vm_ops_data_mmio = 3121static const struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
3155{ 3122{
3156 .open = snd_pcm_mmap_data_open, 3123 .open = snd_pcm_mmap_data_open,
3157 .close = snd_pcm_mmap_data_close, 3124 .close = snd_pcm_mmap_data_close,