Lines Matching refs:card
42 static int snd_ctl_remove_locked(struct snd_card *card,
47 struct snd_card *card; in snd_ctl_open() local
55 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); in snd_ctl_open()
56 if (!card) { in snd_ctl_open()
60 err = snd_card_file_add(card, file); in snd_ctl_open()
65 if (!try_module_get(card->module)) { in snd_ctl_open()
77 ctl->card = card; in snd_ctl_open()
82 scoped_guard(write_lock_irqsave, &card->controls_rwlock) in snd_ctl_open()
83 list_add_tail(&ctl->list, &card->ctl_files); in snd_ctl_open()
84 snd_card_unref(card); in snd_ctl_open()
88 module_put(card->module); in snd_ctl_open()
90 snd_card_file_remove(card, file); in snd_ctl_open()
92 if (card) in snd_ctl_open()
93 snd_card_unref(card); in snd_ctl_open()
111 struct snd_card *card; in snd_ctl_release() local
118 card = ctl->card; in snd_ctl_release()
120 scoped_guard(write_lock_irqsave, &card->controls_rwlock) in snd_ctl_release()
123 scoped_guard(rwsem_write, &card->controls_rwsem) { in snd_ctl_release()
124 list_for_each_entry(control, &card->controls, list) in snd_ctl_release()
134 module_put(card->module); in snd_ctl_release()
135 snd_card_file_remove(card, file); in snd_ctl_release()
149 void snd_ctl_notify(struct snd_card *card, unsigned int mask, in snd_ctl_notify() argument
155 if (snd_BUG_ON(!card || !id)) in snd_ctl_notify()
157 if (card->shutdown) in snd_ctl_notify()
160 guard(read_lock_irqsave)(&card->controls_rwlock); in snd_ctl_notify()
162 card->mixer_oss_change_count++; in snd_ctl_notify()
164 list_for_each_entry(ctl, &card->ctl_files, list) { in snd_ctl_notify()
180 dev_err(card->dev, "No memory available to allocate event\n"); in snd_ctl_notify()
200 void snd_ctl_notify_one(struct snd_card *card, unsigned int mask, in snd_ctl_notify_one() argument
208 snd_ctl_notify(card, mask, &id); in snd_ctl_notify_one()
211 lops->lnotify(card, mask, kctl, ioff); in snd_ctl_notify_one()
333 static bool snd_ctl_remove_numid_conflict(struct snd_card *card, in snd_ctl_remove_numid_conflict() argument
339 if (card->last_numid >= UINT_MAX - count) in snd_ctl_remove_numid_conflict()
340 card->last_numid = 0; in snd_ctl_remove_numid_conflict()
342 list_for_each_entry(kctl, &card->controls, list) { in snd_ctl_remove_numid_conflict()
343 if (kctl->id.numid < card->last_numid + 1 + count && in snd_ctl_remove_numid_conflict()
344 kctl->id.numid + kctl->count > card->last_numid + 1) { in snd_ctl_remove_numid_conflict()
345 card->last_numid = kctl->id.numid + kctl->count - 1; in snd_ctl_remove_numid_conflict()
352 static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) in snd_ctl_find_hole() argument
356 while (snd_ctl_remove_numid_conflict(card, count)) { in snd_ctl_find_hole()
359 dev_err(card->dev, "unable to allocate new control numid\n"); in snd_ctl_find_hole()
400 static void add_hash_entries(struct snd_card *card, in add_hash_entries() argument
406 xa_store_range(&card->ctl_numids, kcontrol->id.numid, in add_hash_entries()
412 if (xa_insert(&card->ctl_hash, get_ctl_id_hash(&id), in add_hash_entries()
415 card->ctl_hash_collision = true; in add_hash_entries()
416 dev_dbg(card->dev, "ctl_hash collision %d:%s:%d\n", in add_hash_entries()
423 static void remove_hash_entries(struct snd_card *card, in remove_hash_entries() argument
432 xa_erase(&card->ctl_numids, id.numid); in remove_hash_entries()
434 matched = xa_load(&card->ctl_hash, h); in remove_hash_entries()
437 xa_erase(&card->ctl_hash, h); in remove_hash_entries()
443 static inline void add_hash_entries(struct snd_card *card, in add_hash_entries() argument
447 static inline void remove_hash_entries(struct snd_card *card, in remove_hash_entries() argument
458 static int __snd_ctl_add_replace(struct snd_card *card, in __snd_ctl_add_replace() argument
467 lockdep_assert_held_write(&card->controls_rwsem); in __snd_ctl_add_replace()
473 old = snd_ctl_find_id(card, &id); in __snd_ctl_add_replace()
479 dev_err(card->dev, in __snd_ctl_add_replace()
486 err = snd_ctl_remove_locked(card, old); in __snd_ctl_add_replace()
491 if (snd_ctl_find_hole(card, kcontrol->count) < 0) in __snd_ctl_add_replace()
494 scoped_guard(write_lock_irq, &card->controls_rwlock) { in __snd_ctl_add_replace()
495 list_add_tail(&kcontrol->list, &card->controls); in __snd_ctl_add_replace()
496 card->controls_count += kcontrol->count; in __snd_ctl_add_replace()
497 kcontrol->id.numid = card->last_numid + 1; in __snd_ctl_add_replace()
498 card->last_numid += kcontrol->count; in __snd_ctl_add_replace()
501 add_hash_entries(card, kcontrol); in __snd_ctl_add_replace()
504 snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_ADD, kcontrol, idx); in __snd_ctl_add_replace()
509 static int snd_ctl_add_replace(struct snd_card *card, in snd_ctl_add_replace() argument
517 if (snd_BUG_ON(!card || !kcontrol->info)) in snd_ctl_add_replace()
520 scoped_guard(rwsem_write, &card->controls_rwsem) in snd_ctl_add_replace()
521 err = __snd_ctl_add_replace(card, kcontrol, mode); in snd_ctl_add_replace()
546 int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) in snd_ctl_add() argument
548 return snd_ctl_add_replace(card, kcontrol, CTL_ADD_EXCLUSIVE); in snd_ctl_add()
566 int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, in snd_ctl_replace() argument
569 return snd_ctl_add_replace(card, kcontrol, in snd_ctl_replace()
574 static int __snd_ctl_remove(struct snd_card *card, in __snd_ctl_remove() argument
580 lockdep_assert_held_write(&card->controls_rwsem); in __snd_ctl_remove()
582 if (snd_BUG_ON(!card || !kcontrol)) in __snd_ctl_remove()
586 remove_hash_entries(card, kcontrol); in __snd_ctl_remove()
588 scoped_guard(write_lock_irq, &card->controls_rwlock) { in __snd_ctl_remove()
590 card->controls_count -= kcontrol->count; in __snd_ctl_remove()
594 snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_REMOVE, kcontrol, idx); in __snd_ctl_remove()
599 static inline int snd_ctl_remove_locked(struct snd_card *card, in snd_ctl_remove_locked() argument
602 return __snd_ctl_remove(card, kcontrol, true); in snd_ctl_remove_locked()
618 int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) in snd_ctl_remove() argument
622 guard(rwsem_write)(&card->controls_rwsem); in snd_ctl_remove()
623 return snd_ctl_remove_locked(card, kcontrol); in snd_ctl_remove()
637 int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) in snd_ctl_remove_id() argument
641 guard(rwsem_write)(&card->controls_rwsem); in snd_ctl_remove_id()
642 kctl = snd_ctl_find_id(card, id); in snd_ctl_remove_id()
645 return snd_ctl_remove_locked(card, kctl); in snd_ctl_remove_id()
662 struct snd_card *card = file->card; in snd_ctl_remove_user_ctl() local
666 guard(rwsem_write)(&card->controls_rwsem); in snd_ctl_remove_user_ctl()
667 kctl = snd_ctl_find_id(card, id); in snd_ctl_remove_user_ctl()
675 return snd_ctl_remove_locked(card, kctl); in snd_ctl_remove_user_ctl()
690 int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, in snd_ctl_activate_id() argument
698 down_write(&card->controls_rwsem); in snd_ctl_activate_id()
699 kctl = snd_ctl_find_id(card, id); in snd_ctl_activate_id()
717 downgrade_write(&card->controls_rwsem); in snd_ctl_activate_id()
718 snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, index_offset); in snd_ctl_activate_id()
719 up_read(&card->controls_rwsem); in snd_ctl_activate_id()
723 up_write(&card->controls_rwsem); in snd_ctl_activate_id()
746 int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, in snd_ctl_rename_id() argument
752 guard(rwsem_write)(&card->controls_rwsem); in snd_ctl_rename_id()
753 kctl = snd_ctl_find_id(card, src_id); in snd_ctl_rename_id()
757 remove_hash_entries(card, kctl); in snd_ctl_rename_id()
760 add_hash_entries(card, kctl); in snd_ctl_rename_id()
775 void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, in snd_ctl_rename() argument
778 guard(rwsem_write)(&card->controls_rwsem); in snd_ctl_rename()
779 remove_hash_entries(card, kctl); in snd_ctl_rename()
785 add_hash_entries(card, kctl); in snd_ctl_rename()
791 snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid) in snd_ctl_find_numid_slow() argument
795 guard(read_lock_irqsave)(&card->controls_rwlock); in snd_ctl_find_numid_slow()
796 list_for_each_entry(kctl, &card->controls, list) { in snd_ctl_find_numid_slow()
815 struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, in snd_ctl_find_numid() argument
818 if (snd_BUG_ON(!card || !numid)) in snd_ctl_find_numid()
822 return xa_load(&card->ctl_numids, numid); in snd_ctl_find_numid()
824 return snd_ctl_find_numid_slow(card, numid); in snd_ctl_find_numid()
840 struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, in snd_ctl_find_id() argument
845 if (snd_BUG_ON(!card || !id)) in snd_ctl_find_id()
849 return snd_ctl_find_numid(card, id->numid); in snd_ctl_find_id()
851 kctl = xa_load(&card->ctl_hash, get_ctl_id_hash(id)); in snd_ctl_find_id()
854 if (!card->ctl_hash_collision) in snd_ctl_find_id()
858 guard(read_lock_irqsave)(&card->controls_rwlock); in snd_ctl_find_id()
859 list_for_each_entry(kctl, &card->controls, list) in snd_ctl_find_id()
867 static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, in snd_ctl_card_info() argument
876 info->card = card->number; in snd_ctl_card_info()
877 strscpy(info->id, card->id, sizeof(info->id)); in snd_ctl_card_info()
878 strscpy(info->driver, card->driver, sizeof(info->driver)); in snd_ctl_card_info()
879 strscpy(info->name, card->shortname, sizeof(info->name)); in snd_ctl_card_info()
880 strscpy(info->longname, card->longname, sizeof(info->longname)); in snd_ctl_card_info()
881 strscpy(info->mixername, card->mixername, sizeof(info->mixername)); in snd_ctl_card_info()
882 strscpy(info->components, card->components, sizeof(info->components)); in snd_ctl_card_info()
889 static int snd_ctl_elem_list(struct snd_card *card, in snd_ctl_elem_list() argument
899 guard(rwsem_read)(&card->controls_rwsem); in snd_ctl_elem_list()
900 list->count = card->controls_count; in snd_ctl_elem_list()
904 list_for_each_entry(kctl, &card->controls, list) { in snd_ctl_elem_list()
922 static int snd_ctl_elem_list_user(struct snd_card *card, in snd_ctl_elem_list_user() argument
930 err = snd_ctl_elem_list(card, &list); in snd_ctl_elem_list_user()
940 static int snd_ctl_check_elem_info(struct snd_card *card, in snd_ctl_check_elem_info() argument
954 if (card) in snd_ctl_check_elem_info()
955 dev_err(card->dev, in snd_ctl_check_elem_info()
964 if (card) in snd_ctl_check_elem_info()
965 dev_err(card->dev, in snd_ctl_check_elem_info()
973 if (card) in snd_ctl_check_elem_info()
974 dev_err(card->dev, in snd_ctl_check_elem_info()
1008 static int sanity_check_int_value(struct snd_card *card, in sanity_check_int_value() argument
1046 dev_err(card->dev, in sanity_check_int_value()
1057 dev_err(card->dev, in sanity_check_int_value()
1070 static int sanity_check_input_values(struct snd_card *card, in sanity_check_input_values() argument
1083 ret = sanity_check_int_value(card, control, info, i, in sanity_check_input_values()
1097 static int sanity_check_elem_value(struct snd_card *card, in sanity_check_elem_value() argument
1106 ret = sanity_check_input_values(card, control, info, true); in sanity_check_elem_value()
1125 static int __snd_ctl_elem_info(struct snd_card *card, in __snd_ctl_elem_info() argument
1153 snd_ctl_check_elem_info(card, info) < 0) in __snd_ctl_elem_info()
1162 struct snd_card *card = ctl->card; in snd_ctl_elem_info() local
1165 guard(rwsem_read)(&card->controls_rwsem); in snd_ctl_elem_info()
1166 kctl = snd_ctl_find_id(card, &info->id); in snd_ctl_elem_info()
1169 return __snd_ctl_elem_info(card, kctl, info, ctl); in snd_ctl_elem_info()
1175 struct snd_card *card = ctl->card; in snd_ctl_elem_info_user() local
1181 result = snd_power_ref_and_wait(card); in snd_ctl_elem_info_user()
1185 snd_power_unref(card); in snd_ctl_elem_info_user()
1196 static int snd_ctl_elem_read(struct snd_card *card, in snd_ctl_elem_read() argument
1206 guard(rwsem_read)(&card->controls_rwsem); in snd_ctl_elem_read()
1207 kctl = snd_ctl_find_id(card, &control->id); in snd_ctl_elem_read()
1222 ret = __snd_ctl_elem_info(card, kctl, &info, NULL); in snd_ctl_elem_read()
1233 sanity_check_elem_value(card, control, &info, pattern) < 0) { in snd_ctl_elem_read()
1234 dev_err(card->dev, in snd_ctl_elem_read()
1244 static int snd_ctl_elem_read_user(struct snd_card *card, in snd_ctl_elem_read_user() argument
1254 result = snd_power_ref_and_wait(card); in snd_ctl_elem_read_user()
1257 result = snd_ctl_elem_read(card, control); in snd_ctl_elem_read_user()
1258 snd_power_unref(card); in snd_ctl_elem_read_user()
1267 static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, in snd_ctl_elem_write() argument
1275 down_write(&card->controls_rwsem); in snd_ctl_elem_write()
1276 kctl = snd_ctl_find_id(card, &control->id); in snd_ctl_elem_write()
1278 up_write(&card->controls_rwsem); in snd_ctl_elem_write()
1286 up_write(&card->controls_rwsem); in snd_ctl_elem_write()
1297 result = __snd_ctl_elem_info(card, kctl, &info, NULL); in snd_ctl_elem_write()
1299 result = sanity_check_input_values(card, control, &info, in snd_ctl_elem_write()
1305 up_write(&card->controls_rwsem); in snd_ctl_elem_write()
1310 downgrade_write(&card->controls_rwsem); in snd_ctl_elem_write()
1311 snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_VALUE, kctl, index_offset); in snd_ctl_elem_write()
1312 up_read(&card->controls_rwsem); in snd_ctl_elem_write()
1314 up_write(&card->controls_rwsem); in snd_ctl_elem_write()
1324 struct snd_card *card; in snd_ctl_elem_write_user() local
1331 card = file->card; in snd_ctl_elem_write_user()
1332 result = snd_power_ref_and_wait(card); in snd_ctl_elem_write_user()
1335 result = snd_ctl_elem_write(card, file, control); in snd_ctl_elem_write_user()
1336 snd_power_unref(card); in snd_ctl_elem_write_user()
1348 struct snd_card *card = file->card; in snd_ctl_elem_lock() local
1355 guard(rwsem_write)(&card->controls_rwsem); in snd_ctl_elem_lock()
1356 kctl = snd_ctl_find_id(card, &id); in snd_ctl_elem_lock()
1369 struct snd_card *card = file->card; in snd_ctl_elem_unlock() local
1376 guard(rwsem_write)(&card->controls_rwsem); in snd_ctl_elem_unlock()
1377 kctl = snd_ctl_find_id(card, &id); in snd_ctl_elem_unlock()
1391 struct snd_card *card; member
1400 static bool check_user_elem_overflow(struct snd_card *card, ssize_t add) in check_user_elem_overflow() argument
1402 return (ssize_t)card->user_ctl_alloc_size + add > max_user_ctl_alloc_size; in check_user_elem_overflow()
1464 err = sanity_check_input_values(ue->card, ucontrol, &ue->info, false); in snd_ctl_elem_user_put()
1484 lockdep_assert_held_write(&ue->card->controls_rwsem); in replace_user_tlv()
1490 if (check_user_elem_overflow(ue->card, (ssize_t)(size - ue->tlv_data_size))) in replace_user_tlv()
1511 ue->card->user_ctl_alloc_size -= ue->tlv_data_size; in replace_user_tlv()
1519 ue->card->user_ctl_alloc_size += size; in replace_user_tlv()
1523 snd_ctl_notify_one(ue->card, mask, kctl, i); in replace_user_tlv()
1562 lockdep_assert_held_write(&ue->card->controls_rwsem); in snd_ctl_elem_init_enum_names()
1568 if (check_user_elem_overflow(ue->card, buf_len)) in snd_ctl_elem_init_enum_names()
1589 ue->card->user_ctl_alloc_size += ue->info.value.enumerated.names_length; in snd_ctl_elem_init_enum_names()
1604 ue->card->user_ctl_alloc_size -= compute_user_elem_size(ue->elem_data_size, kcontrol->count); in snd_ctl_elem_user_free()
1605 ue->card->user_ctl_alloc_size -= ue->tlv_data_size; in snd_ctl_elem_user_free()
1607 ue->card->user_ctl_alloc_size -= ue->info.value.enumerated.names_length; in snd_ctl_elem_user_free()
1617 struct snd_card *card = file->card; in snd_ctl_elem_add() local
1674 guard(rwsem_write)(&card->controls_rwsem); in snd_ctl_elem_add()
1675 if (check_user_elem_overflow(card, alloc_size)) in snd_ctl_elem_add()
1697 card->user_ctl_alloc_size += alloc_size; in snd_ctl_elem_add()
1700 ue->card = card; in snd_ctl_elem_add()
1726 err = __snd_ctl_add_replace(card, kctl, CTL_ADD_EXCLUSIVE); in snd_ctl_elem_add()
1861 lockdep_assert_held(&file->card->controls_rwsem); in snd_ctl_tlv_ioctl()
1876 kctl = snd_ctl_find_numid(file->card, header.numid); in snd_ctl_tlv_ioctl()
1902 struct snd_card *card; in snd_ctl_ioctl() local
1909 card = ctl->card; in snd_ctl_ioctl()
1910 if (snd_BUG_ON(!card)) in snd_ctl_ioctl()
1916 return snd_ctl_card_info(card, ctl, cmd, argp); in snd_ctl_ioctl()
1918 return snd_ctl_elem_list_user(card, argp); in snd_ctl_ioctl()
1922 return snd_ctl_elem_read_user(card, argp); in snd_ctl_ioctl()
1938 err = snd_power_ref_and_wait(card); in snd_ctl_ioctl()
1941 scoped_guard(rwsem_read, &card->controls_rwsem) in snd_ctl_ioctl()
1943 snd_power_unref(card); in snd_ctl_ioctl()
1946 err = snd_power_ref_and_wait(card); in snd_ctl_ioctl()
1949 scoped_guard(rwsem_write, &card->controls_rwsem) in snd_ctl_ioctl()
1951 snd_power_unref(card); in snd_ctl_ioctl()
1954 err = snd_power_ref_and_wait(card); in snd_ctl_ioctl()
1957 scoped_guard(rwsem_write, &card->controls_rwsem) in snd_ctl_ioctl()
1959 snd_power_unref(card); in snd_ctl_ioctl()
1969 err = p->fioctl(card, ctl, cmd, arg); in snd_ctl_ioctl()
1973 dev_dbg(card->dev, "unknown ioctl = 0x%x\n", cmd); in snd_ctl_ioctl()
1985 if (snd_BUG_ON(!ctl || !ctl->card)) in snd_ctl_read()
2007 if (ctl->card->shutdown) in snd_ctl_read()
2158 int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type) in snd_ctl_get_preferred_subdevice() argument
2163 guard(read_lock_irqsave)(&card->controls_rwlock); in snd_ctl_get_preferred_subdevice()
2164 list_for_each_entry(kctl, &card->ctl_files, list) { in snd_ctl_get_preferred_subdevice()
2218 struct snd_card *card; in snd_ctl_register_layer() local
2226 card = snd_card_ref(card_number); in snd_ctl_register_layer()
2227 if (card) { in snd_ctl_register_layer()
2228 scoped_guard(rwsem_read, &card->controls_rwsem) in snd_ctl_register_layer()
2229 lops->lregister(card); in snd_ctl_register_layer()
2230 snd_card_unref(card); in snd_ctl_register_layer()
2293 struct snd_card *card = device->device_data; in snd_ctl_dev_register() local
2296 err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1, in snd_ctl_dev_register()
2297 &snd_ctl_f_ops, card, card->ctl_dev); in snd_ctl_dev_register()
2300 call_snd_ctl_lops(card, lregister); in snd_ctl_dev_register()
2309 struct snd_card *card = device->device_data; in snd_ctl_dev_disconnect() local
2312 scoped_guard(read_lock_irqsave, &card->controls_rwlock) { in snd_ctl_dev_disconnect()
2313 list_for_each_entry(ctl, &card->ctl_files, list) { in snd_ctl_dev_disconnect()
2319 call_snd_ctl_lops(card, ldisconnect); in snd_ctl_dev_disconnect()
2320 return snd_unregister_device(card->ctl_dev); in snd_ctl_dev_disconnect()
2328 struct snd_card *card = device->device_data; in snd_ctl_dev_free() local
2331 scoped_guard(rwsem_write, &card->controls_rwsem) { in snd_ctl_dev_free()
2332 while (!list_empty(&card->controls)) { in snd_ctl_dev_free()
2333 control = snd_kcontrol(card->controls.next); in snd_ctl_dev_free()
2334 __snd_ctl_remove(card, control, false); in snd_ctl_dev_free()
2338 xa_destroy(&card->ctl_numids); in snd_ctl_dev_free()
2339 xa_destroy(&card->ctl_hash); in snd_ctl_dev_free()
2342 put_device(card->ctl_dev); in snd_ctl_dev_free()
2350 int snd_ctl_create(struct snd_card *card) in snd_ctl_create() argument
2359 if (snd_BUG_ON(!card)) in snd_ctl_create()
2361 if (snd_BUG_ON(card->number < 0 || card->number >= SNDRV_CARDS)) in snd_ctl_create()
2364 err = snd_device_alloc(&card->ctl_dev, card); in snd_ctl_create()
2367 dev_set_name(card->ctl_dev, "controlC%d", card->number); in snd_ctl_create()
2369 err = snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops); in snd_ctl_create()
2371 put_device(card->ctl_dev); in snd_ctl_create()