diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-03-18 13:22:33 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-03-18 13:22:33 -0400 |
commit | 44c76a960a62fcc46cbcaa0a22a34e666a729329 (patch) | |
tree | d3887c858f6adffb6714da3cdc0059f93588344c /sound/core | |
parent | dbf117cbb9c89991727d42e3161e68b868a1b6ae (diff) | |
parent | c6b76d1f02e2ab1109d8549877a3a24c6a2b4587 (diff) |
Merge branch 'topic/misc' into for-linus
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/control.c | 2 | ||||
-rw-r--r-- | sound/core/init.c | 169 | ||||
-rw-r--r-- | sound/core/misc.c | 2 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 3 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 15 |
5 files changed, 114 insertions, 77 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 819a5c579a39..2487a6bb1c54 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -1313,7 +1313,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, | |||
1313 | err = -EPERM; | 1313 | err = -EPERM; |
1314 | goto __kctl_end; | 1314 | goto __kctl_end; |
1315 | } | 1315 | } |
1316 | err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); | 1316 | err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); |
1317 | if (err > 0) { | 1317 | if (err > 0) { |
1318 | up_read(&card->controls_rwsem); | 1318 | up_read(&card->controls_rwsem); |
1319 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); | 1319 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); |
diff --git a/sound/core/init.c b/sound/core/init.c index 3ac49b1b7cb8..068cf08d3ffb 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -480,74 +480,104 @@ int snd_card_free(struct snd_card *card) | |||
480 | 480 | ||
481 | EXPORT_SYMBOL(snd_card_free); | 481 | EXPORT_SYMBOL(snd_card_free); |
482 | 482 | ||
483 | static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid) | 483 | /* retrieve the last word of shortname or longname */ |
484 | static const char *retrieve_id_from_card_name(const char *name) | ||
484 | { | 485 | { |
485 | int i, len, idx_flag = 0, loops = SNDRV_CARDS; | 486 | const char *spos = name; |
486 | const char *spos, *src; | 487 | |
487 | char *id; | 488 | while (*name) { |
488 | 489 | if (isspace(*name) && isalnum(name[1])) | |
489 | if (nid == NULL) { | 490 | spos = name + 1; |
490 | id = card->shortname; | 491 | name++; |
491 | spos = src = id; | ||
492 | while (*id != '\0') { | ||
493 | if (*id == ' ') | ||
494 | spos = id + 1; | ||
495 | id++; | ||
496 | } | ||
497 | } else { | ||
498 | spos = src = nid; | ||
499 | } | 492 | } |
500 | id = card->id; | 493 | return spos; |
501 | while (*spos != '\0' && !isalnum(*spos)) | 494 | } |
502 | spos++; | 495 | |
503 | if (isdigit(*spos)) | 496 | /* return true if the given id string doesn't conflict any other card ids */ |
504 | *id++ = isalpha(src[0]) ? src[0] : 'D'; | 497 | static bool card_id_ok(struct snd_card *card, const char *id) |
505 | while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) { | 498 | { |
506 | if (isalnum(*spos)) | 499 | int i; |
507 | *id++ = *spos; | 500 | if (!snd_info_check_reserved_words(id)) |
508 | spos++; | 501 | return false; |
502 | for (i = 0; i < snd_ecards_limit; i++) { | ||
503 | if (snd_cards[i] && snd_cards[i] != card && | ||
504 | !strcmp(snd_cards[i]->id, id)) | ||
505 | return false; | ||
509 | } | 506 | } |
510 | *id = '\0'; | 507 | return true; |
508 | } | ||
511 | 509 | ||
512 | id = card->id; | 510 | /* copy to card->id only with valid letters from nid */ |
511 | static void copy_valid_id_string(struct snd_card *card, const char *src, | ||
512 | const char *nid) | ||
513 | { | ||
514 | char *id = card->id; | ||
515 | |||
516 | while (*nid && !isalnum(*nid)) | ||
517 | nid++; | ||
518 | if (isdigit(*nid)) | ||
519 | *id++ = isalpha(*src) ? *src : 'D'; | ||
520 | while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) { | ||
521 | if (isalnum(*nid)) | ||
522 | *id++ = *nid; | ||
523 | nid++; | ||
524 | } | ||
525 | *id = 0; | ||
526 | } | ||
527 | |||
528 | /* Set card->id from the given string | ||
529 | * If the string conflicts with other ids, add a suffix to make it unique. | ||
530 | */ | ||
531 | static void snd_card_set_id_no_lock(struct snd_card *card, const char *src, | ||
532 | const char *nid) | ||
533 | { | ||
534 | int len, loops; | ||
535 | bool with_suffix; | ||
536 | bool is_default = false; | ||
537 | char *id; | ||
513 | 538 | ||
514 | if (*id == '\0') | 539 | copy_valid_id_string(card, src, nid); |
540 | id = card->id; | ||
541 | |||
542 | again: | ||
543 | /* use "Default" for obviously invalid strings | ||
544 | * ("card" conflicts with proc directories) | ||
545 | */ | ||
546 | if (!*id || !strncmp(id, "card", 4)) { | ||
515 | strcpy(id, "Default"); | 547 | strcpy(id, "Default"); |
548 | is_default = true; | ||
549 | } | ||
516 | 550 | ||
517 | while (1) { | 551 | with_suffix = false; |
518 | if (loops-- == 0) { | 552 | for (loops = 0; loops < SNDRV_CARDS; loops++) { |
519 | snd_printk(KERN_ERR "unable to set card id (%s)\n", id); | 553 | if (card_id_ok(card, id)) |
520 | strcpy(card->id, card->proc_root->name); | 554 | return; /* OK */ |
521 | return; | ||
522 | } | ||
523 | if (!snd_info_check_reserved_words(id)) | ||
524 | goto __change; | ||
525 | for (i = 0; i < snd_ecards_limit; i++) { | ||
526 | if (snd_cards[i] && !strcmp(snd_cards[i]->id, id)) | ||
527 | goto __change; | ||
528 | } | ||
529 | break; | ||
530 | 555 | ||
531 | __change: | ||
532 | len = strlen(id); | 556 | len = strlen(id); |
533 | if (idx_flag) { | 557 | if (!with_suffix) { |
534 | if (id[len-1] != '9') | 558 | /* add the "_X" suffix */ |
535 | id[len-1]++; | 559 | char *spos = id + len; |
536 | else | 560 | if (len > sizeof(card->id) - 3) |
537 | id[len-1] = 'A'; | 561 | spos = id + sizeof(card->id) - 3; |
538 | } else if ((size_t)len <= sizeof(card->id) - 3) { | 562 | strcpy(spos, "_1"); |
539 | strcat(id, "_1"); | 563 | with_suffix = true; |
540 | idx_flag++; | ||
541 | } else { | 564 | } else { |
542 | spos = id + len - 2; | 565 | /* modify the existing suffix */ |
543 | if ((size_t)len <= sizeof(card->id) - 2) | 566 | if (id[len - 1] != '9') |
544 | spos++; | 567 | id[len - 1]++; |
545 | *(char *)spos++ = '_'; | 568 | else |
546 | *(char *)spos++ = '1'; | 569 | id[len - 1] = 'A'; |
547 | *(char *)spos++ = '\0'; | ||
548 | idx_flag++; | ||
549 | } | 570 | } |
550 | } | 571 | } |
572 | /* fallback to the default id */ | ||
573 | if (!is_default) { | ||
574 | *id = 0; | ||
575 | goto again; | ||
576 | } | ||
577 | /* last resort... */ | ||
578 | snd_printk(KERN_ERR "unable to set card id (%s)\n", id); | ||
579 | if (card->proc_root->name) | ||
580 | strcpy(card->id, card->proc_root->name); | ||
551 | } | 581 | } |
552 | 582 | ||
553 | /** | 583 | /** |
@@ -564,7 +594,7 @@ void snd_card_set_id(struct snd_card *card, const char *nid) | |||
564 | if (card->id[0] != '\0') | 594 | if (card->id[0] != '\0') |
565 | return; | 595 | return; |
566 | mutex_lock(&snd_card_mutex); | 596 | mutex_lock(&snd_card_mutex); |
567 | snd_card_set_id_no_lock(card, nid); | 597 | snd_card_set_id_no_lock(card, nid, nid); |
568 | mutex_unlock(&snd_card_mutex); | 598 | mutex_unlock(&snd_card_mutex); |
569 | } | 599 | } |
570 | EXPORT_SYMBOL(snd_card_set_id); | 600 | EXPORT_SYMBOL(snd_card_set_id); |
@@ -596,22 +626,12 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr, | |||
596 | memcpy(buf1, buf, copy); | 626 | memcpy(buf1, buf, copy); |
597 | buf1[copy] = '\0'; | 627 | buf1[copy] = '\0'; |
598 | mutex_lock(&snd_card_mutex); | 628 | mutex_lock(&snd_card_mutex); |
599 | if (!snd_info_check_reserved_words(buf1)) { | 629 | if (!card_id_ok(NULL, buf1)) { |
600 | __exist: | ||
601 | mutex_unlock(&snd_card_mutex); | 630 | mutex_unlock(&snd_card_mutex); |
602 | return -EEXIST; | 631 | return -EEXIST; |
603 | } | 632 | } |
604 | for (idx = 0; idx < snd_ecards_limit; idx++) { | ||
605 | if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) { | ||
606 | if (card == snd_cards[idx]) | ||
607 | goto __ok; | ||
608 | else | ||
609 | goto __exist; | ||
610 | } | ||
611 | } | ||
612 | strcpy(card->id, buf1); | 633 | strcpy(card->id, buf1); |
613 | snd_info_card_id_change(card); | 634 | snd_info_card_id_change(card); |
614 | __ok: | ||
615 | mutex_unlock(&snd_card_mutex); | 635 | mutex_unlock(&snd_card_mutex); |
616 | 636 | ||
617 | return count; | 637 | return count; |
@@ -665,7 +685,18 @@ int snd_card_register(struct snd_card *card) | |||
665 | mutex_unlock(&snd_card_mutex); | 685 | mutex_unlock(&snd_card_mutex); |
666 | return 0; | 686 | return 0; |
667 | } | 687 | } |
668 | snd_card_set_id_no_lock(card, card->id[0] == '\0' ? NULL : card->id); | 688 | if (*card->id) { |
689 | /* make a unique id name from the given string */ | ||
690 | char tmpid[sizeof(card->id)]; | ||
691 | memcpy(tmpid, card->id, sizeof(card->id)); | ||
692 | snd_card_set_id_no_lock(card, tmpid, tmpid); | ||
693 | } else { | ||
694 | /* create an id from either shortname or longname */ | ||
695 | const char *src; | ||
696 | src = *card->shortname ? card->shortname : card->longname; | ||
697 | snd_card_set_id_no_lock(card, src, | ||
698 | retrieve_id_from_card_name(src)); | ||
699 | } | ||
669 | snd_cards[card->number] = card; | 700 | snd_cards[card->number] = card; |
670 | mutex_unlock(&snd_card_mutex); | 701 | mutex_unlock(&snd_card_mutex); |
671 | init_info_for_card(card); | 702 | init_info_for_card(card); |
diff --git a/sound/core/misc.c b/sound/core/misc.c index 465f0ce772cb..768167925409 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c | |||
@@ -72,7 +72,7 @@ void __snd_printk(unsigned int level, const char *path, int line, | |||
72 | char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; | 72 | char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | #ifdef CONFIG_SND_DEBUG | 75 | #ifdef CONFIG_SND_DEBUG |
76 | if (debug < level) | 76 | if (debug < level) |
77 | return; | 77 | return; |
78 | #endif | 78 | #endif |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 3420bd3da5d7..4d18941178e6 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1029,7 +1029,8 @@ static int snd_interval_ratden(struct snd_interval *i, | |||
1029 | * | 1029 | * |
1030 | * Returns non-zero if the value is changed, zero if not changed. | 1030 | * Returns non-zero if the value is changed, zero if not changed. |
1031 | */ | 1031 | */ |
1032 | int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask) | 1032 | int snd_interval_list(struct snd_interval *i, unsigned int count, |
1033 | const unsigned int *list, unsigned int mask) | ||
1033 | { | 1034 | { |
1034 | unsigned int k; | 1035 | unsigned int k; |
1035 | struct snd_interval list_range; | 1036 | struct snd_interval list_range; |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 25ed9fe41b89..3fe99e644eb8 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -1586,12 +1586,18 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) | |||
1586 | struct file *file; | 1586 | struct file *file; |
1587 | struct snd_pcm_file *pcm_file; | 1587 | struct snd_pcm_file *pcm_file; |
1588 | struct snd_pcm_substream *substream1; | 1588 | struct snd_pcm_substream *substream1; |
1589 | struct snd_pcm_group *group; | ||
1589 | 1590 | ||
1590 | file = snd_pcm_file_fd(fd); | 1591 | file = snd_pcm_file_fd(fd); |
1591 | if (!file) | 1592 | if (!file) |
1592 | return -EBADFD; | 1593 | return -EBADFD; |
1593 | pcm_file = file->private_data; | 1594 | pcm_file = file->private_data; |
1594 | substream1 = pcm_file->substream; | 1595 | substream1 = pcm_file->substream; |
1596 | group = kmalloc(sizeof(*group), GFP_KERNEL); | ||
1597 | if (!group) { | ||
1598 | res = -ENOMEM; | ||
1599 | goto _nolock; | ||
1600 | } | ||
1595 | down_write(&snd_pcm_link_rwsem); | 1601 | down_write(&snd_pcm_link_rwsem); |
1596 | write_lock_irq(&snd_pcm_link_rwlock); | 1602 | write_lock_irq(&snd_pcm_link_rwlock); |
1597 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || | 1603 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || |
@@ -1604,11 +1610,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) | |||
1604 | goto _end; | 1610 | goto _end; |
1605 | } | 1611 | } |
1606 | if (!snd_pcm_stream_linked(substream)) { | 1612 | if (!snd_pcm_stream_linked(substream)) { |
1607 | substream->group = kmalloc(sizeof(struct snd_pcm_group), GFP_ATOMIC); | 1613 | substream->group = group; |
1608 | if (substream->group == NULL) { | ||
1609 | res = -ENOMEM; | ||
1610 | goto _end; | ||
1611 | } | ||
1612 | spin_lock_init(&substream->group->lock); | 1614 | spin_lock_init(&substream->group->lock); |
1613 | INIT_LIST_HEAD(&substream->group->substreams); | 1615 | INIT_LIST_HEAD(&substream->group->substreams); |
1614 | list_add_tail(&substream->link_list, &substream->group->substreams); | 1616 | list_add_tail(&substream->link_list, &substream->group->substreams); |
@@ -1620,7 +1622,10 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) | |||
1620 | _end: | 1622 | _end: |
1621 | write_unlock_irq(&snd_pcm_link_rwlock); | 1623 | write_unlock_irq(&snd_pcm_link_rwlock); |
1622 | up_write(&snd_pcm_link_rwsem); | 1624 | up_write(&snd_pcm_link_rwsem); |
1625 | _nolock: | ||
1623 | fput(file); | 1626 | fput(file); |
1627 | if (res < 0) | ||
1628 | kfree(group); | ||
1624 | return res; | 1629 | return res; |
1625 | } | 1630 | } |
1626 | 1631 | ||