hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/sound/core/info.c
....@@ -1,22 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Information interface for ALSA driver
34 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4
- *
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
- *
205 */
216
227 #include <linux/init.h>
....@@ -35,7 +20,7 @@
3520
3621 int snd_info_check_reserved_words(const char *str)
3722 {
38
- static char *reserved[] =
23
+ static const char * const reserved[] =
3924 {
4025 "version",
4126 "meminfo",
....@@ -50,7 +35,7 @@
5035 "seq",
5136 NULL
5237 };
53
- char **xstr = reserved;
38
+ const char * const *xstr = reserved;
5439
5540 while (*xstr) {
5641 if (!strcmp(*xstr, str))
....@@ -127,9 +112,9 @@
127112 entry = data->entry;
128113 mutex_lock(&entry->access);
129114 if (entry->c.ops->llseek) {
130
- offset = entry->c.ops->llseek(entry,
131
- data->file_private_data,
132
- file, offset, orig);
115
+ ret = entry->c.ops->llseek(entry,
116
+ data->file_private_data,
117
+ file, offset, orig);
133118 goto out;
134119 }
135120
....@@ -297,17 +282,16 @@
297282 return 0;
298283 }
299284
300
-static const struct file_operations snd_info_entry_operations =
285
+static const struct proc_ops snd_info_entry_operations =
301286 {
302
- .owner = THIS_MODULE,
303
- .llseek = snd_info_entry_llseek,
304
- .read = snd_info_entry_read,
305
- .write = snd_info_entry_write,
306
- .poll = snd_info_entry_poll,
307
- .unlocked_ioctl = snd_info_entry_ioctl,
308
- .mmap = snd_info_entry_mmap,
309
- .open = snd_info_entry_open,
310
- .release = snd_info_entry_release,
287
+ .proc_lseek = snd_info_entry_llseek,
288
+ .proc_read = snd_info_entry_read,
289
+ .proc_write = snd_info_entry_write,
290
+ .proc_poll = snd_info_entry_poll,
291
+ .proc_ioctl = snd_info_entry_ioctl,
292
+ .proc_mmap = snd_info_entry_mmap,
293
+ .proc_open = snd_info_entry_open,
294
+ .proc_release = snd_info_entry_release,
311295 };
312296
313297 /*
....@@ -436,33 +420,21 @@
436420 return 0;
437421 }
438422
439
-static const struct file_operations snd_info_text_entry_ops =
423
+static const struct proc_ops snd_info_text_entry_ops =
440424 {
441
- .owner = THIS_MODULE,
442
- .open = snd_info_text_entry_open,
443
- .release = snd_info_text_entry_release,
444
- .write = snd_info_text_entry_write,
445
- .llseek = seq_lseek,
446
- .read = seq_read,
425
+ .proc_open = snd_info_text_entry_open,
426
+ .proc_release = snd_info_text_entry_release,
427
+ .proc_write = snd_info_text_entry_write,
428
+ .proc_lseek = seq_lseek,
429
+ .proc_read = seq_read,
447430 };
448431
449
-/*
450
- * snd_info_create_subdir - create and register a subdir for a given parent
451
- * @mod: the module pointer
452
- * @name: the module name
453
- * @parent: the parent directory
454
- *
455
- * Creates and registers new subdir entry inside a given parent.
456
- *
457
- * Return: The pointer of the new instance, or NULL on failure.
458
- */
459
-struct snd_info_entry *snd_info_create_subdir(struct module *mod,
460
- const char *name,
461
- struct snd_info_entry *parent)
432
+static struct snd_info_entry *create_subdir(struct module *mod,
433
+ const char *name)
462434 {
463435 struct snd_info_entry *entry;
464436
465
- entry = snd_info_create_module_entry(mod, name, parent);
437
+ entry = snd_info_create_module_entry(mod, name, NULL);
466438 if (!entry)
467439 return NULL;
468440 entry->mode = S_IFDIR | 0555;
....@@ -472,14 +444,14 @@
472444 }
473445 return entry;
474446 }
475
-EXPORT_SYMBOL(snd_info_create_subdir);
476447
477448 static struct snd_info_entry *
478
-snd_info_create_entry(const char *name, struct snd_info_entry *parent);
449
+snd_info_create_entry(const char *name, struct snd_info_entry *parent,
450
+ struct module *module);
479451
480452 int __init snd_info_init(void)
481453 {
482
- snd_proc_root = snd_info_create_entry("asound", NULL);
454
+ snd_proc_root = snd_info_create_entry("asound", NULL, THIS_MODULE);
483455 if (!snd_proc_root)
484456 return -ENOMEM;
485457 snd_proc_root->mode = S_IFDIR | 0555;
....@@ -487,12 +459,12 @@
487459 if (!snd_proc_root->p)
488460 goto error;
489461 #ifdef CONFIG_SND_OSSEMUL
490
- snd_oss_root = snd_info_create_subdir(THIS_MODULE, "oss", NULL);
462
+ snd_oss_root = create_subdir(THIS_MODULE, "oss");
491463 if (!snd_oss_root)
492464 goto error;
493465 #endif
494466 #if IS_ENABLED(CONFIG_SND_SEQUENCER)
495
- snd_seq_root = snd_info_create_subdir(THIS_MODULE, "seq", NULL);
467
+ snd_seq_root = create_subdir(THIS_MODULE, "seq");
496468 if (!snd_seq_root)
497469 goto error;
498470 #endif
....@@ -515,6 +487,14 @@
515487 return 0;
516488 }
517489
490
+static void snd_card_id_read(struct snd_info_entry *entry,
491
+ struct snd_info_buffer *buffer)
492
+{
493
+ struct snd_card *card = entry->private_data;
494
+
495
+ snd_iprintf(buffer, "%s\n", card->id);
496
+}
497
+
518498 /*
519499 * create a card proc file
520500 * called from init.c
....@@ -528,32 +508,12 @@
528508 return -ENXIO;
529509
530510 sprintf(str, "card%i", card->number);
531
- entry = snd_info_create_subdir(card->module, str, NULL);
511
+ entry = create_subdir(card->module, str);
532512 if (!entry)
533513 return -ENOMEM;
534514 card->proc_root = entry;
535
- return 0;
536
-}
537515
538
-/* register all pending info entries */
539
-static int snd_info_register_recursive(struct snd_info_entry *entry)
540
-{
541
- struct snd_info_entry *p;
542
- int err;
543
-
544
- if (!entry->p) {
545
- err = snd_info_register(entry);
546
- if (err < 0)
547
- return err;
548
- }
549
-
550
- list_for_each_entry(p, &entry->children, list) {
551
- err = snd_info_register_recursive(p);
552
- if (err < 0)
553
- return err;
554
- }
555
-
556
- return 0;
516
+ return snd_card_ro_proc_new(card, "id", card, snd_card_id_read);
557517 }
558518
559519 /*
....@@ -569,7 +529,7 @@
569529 if (snd_BUG_ON(!card))
570530 return -ENXIO;
571531
572
- err = snd_info_register_recursive(card->proc_root);
532
+ err = snd_info_register(card->proc_root);
573533 if (err < 0)
574534 return err;
575535
....@@ -631,6 +591,7 @@
631591 return 0;
632592 }
633593
594
+
634595 /**
635596 * snd_info_get_line - read one line from the procfs buffer
636597 * @buffer: the procfs buffer
....@@ -643,7 +604,7 @@
643604 */
644605 int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len)
645606 {
646
- int c = -1;
607
+ int c;
647608
648609 if (snd_BUG_ON(!buffer))
649610 return 1;
....@@ -718,7 +679,8 @@
718679 * Return: The pointer of the new instance, or %NULL on failure.
719680 */
720681 static struct snd_info_entry *
721
-snd_info_create_entry(const char *name, struct snd_info_entry *parent)
682
+snd_info_create_entry(const char *name, struct snd_info_entry *parent,
683
+ struct module *module)
722684 {
723685 struct snd_info_entry *entry;
724686 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
....@@ -735,6 +697,7 @@
735697 INIT_LIST_HEAD(&entry->children);
736698 INIT_LIST_HEAD(&entry->list);
737699 entry->parent = parent;
700
+ entry->module = module;
738701 if (parent) {
739702 mutex_lock(&parent->access);
740703 list_add_tail(&entry->list, &parent->children);
....@@ -757,10 +720,9 @@
757720 const char *name,
758721 struct snd_info_entry *parent)
759722 {
760
- struct snd_info_entry *entry = snd_info_create_entry(name, parent);
761
- if (entry)
762
- entry->module = module;
763
- return entry;
723
+ if (!parent)
724
+ parent = snd_proc_root;
725
+ return snd_info_create_entry(name, parent, module);
764726 }
765727 EXPORT_SYMBOL(snd_info_create_module_entry);
766728
....@@ -778,12 +740,9 @@
778740 const char *name,
779741 struct snd_info_entry * parent)
780742 {
781
- struct snd_info_entry *entry = snd_info_create_entry(name, parent);
782
- if (entry) {
783
- entry->module = card->module;
784
- entry->card = card;
785
- }
786
- return entry;
743
+ if (!parent)
744
+ parent = card->proc_root;
745
+ return snd_info_create_entry(name, parent, card->module);
787746 }
788747 EXPORT_SYMBOL(snd_info_create_card_entry);
789748
....@@ -834,15 +793,7 @@
834793 }
835794 EXPORT_SYMBOL(snd_info_free_entry);
836795
837
-/**
838
- * snd_info_register - register the info entry
839
- * @entry: the info entry
840
- *
841
- * Registers the proc info entry.
842
- *
843
- * Return: Zero if successful, or a negative error code on failure.
844
- */
845
-int snd_info_register(struct snd_info_entry * entry)
796
+static int __snd_info_register(struct snd_info_entry *entry)
846797 {
847798 struct proc_dir_entry *root, *p = NULL;
848799
....@@ -850,6 +801,8 @@
850801 return -ENXIO;
851802 root = entry->parent == NULL ? snd_proc_root->p : entry->parent->p;
852803 mutex_lock(&info_mutex);
804
+ if (entry->p || !root)
805
+ goto unlock;
853806 if (S_ISDIR(entry->mode)) {
854807 p = proc_mkdir_mode(entry->name, entry->mode, root);
855808 if (!p) {
....@@ -857,7 +810,7 @@
857810 return -ENOMEM;
858811 }
859812 } else {
860
- const struct file_operations *ops;
813
+ const struct proc_ops *ops;
861814 if (entry->content == SNDRV_INFO_CONTENT_DATA)
862815 ops = &snd_info_entry_operations;
863816 else
....@@ -871,11 +824,73 @@
871824 proc_set_size(p, entry->size);
872825 }
873826 entry->p = p;
827
+ unlock:
874828 mutex_unlock(&info_mutex);
875829 return 0;
876830 }
831
+
832
+/**
833
+ * snd_info_register - register the info entry
834
+ * @entry: the info entry
835
+ *
836
+ * Registers the proc info entry.
837
+ * The all children entries are registered recursively.
838
+ *
839
+ * Return: Zero if successful, or a negative error code on failure.
840
+ */
841
+int snd_info_register(struct snd_info_entry *entry)
842
+{
843
+ struct snd_info_entry *p;
844
+ int err;
845
+
846
+ if (!entry->p) {
847
+ err = __snd_info_register(entry);
848
+ if (err < 0)
849
+ return err;
850
+ }
851
+
852
+ list_for_each_entry(p, &entry->children, list) {
853
+ err = snd_info_register(p);
854
+ if (err < 0)
855
+ return err;
856
+ }
857
+
858
+ return 0;
859
+}
877860 EXPORT_SYMBOL(snd_info_register);
878861
862
+/**
863
+ * snd_card_rw_proc_new - Create a read/write text proc file entry for the card
864
+ * @card: the card instance
865
+ * @name: the file name
866
+ * @private_data: the arbitrary private data
867
+ * @read: the read callback
868
+ * @write: the write callback, NULL for read-only
869
+ *
870
+ * This proc file entry will be registered via snd_card_register() call, and
871
+ * it will be removed automatically at the card removal, too.
872
+ */
873
+int snd_card_rw_proc_new(struct snd_card *card, const char *name,
874
+ void *private_data,
875
+ void (*read)(struct snd_info_entry *,
876
+ struct snd_info_buffer *),
877
+ void (*write)(struct snd_info_entry *entry,
878
+ struct snd_info_buffer *buffer))
879
+{
880
+ struct snd_info_entry *entry;
881
+
882
+ entry = snd_info_create_card_entry(card, name, card->proc_root);
883
+ if (!entry)
884
+ return -ENOMEM;
885
+ snd_info_set_text_ops(entry, private_data, read);
886
+ if (write) {
887
+ entry->mode |= 0200;
888
+ entry->c.text.write = write;
889
+ }
890
+ return 0;
891
+}
892
+EXPORT_SYMBOL_GPL(snd_card_rw_proc_new);
893
+
879894 /*
880895
881896 */