浏览代码

ALSA: Introduce snd_card_create()

Introduced snd_card_create() function as a replacement of snd_card_new().
The new function returns a negative error code so that the probe callback
can return the proper error code, while snd_card_new() can give only NULL
check.

The old snd_card_new() is still provided as an inline function but with
__deprecated attribute.  It'll be removed soon later.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 16 年之前
父节点
当前提交
53fb1e6359
共有 2 个文件被更改,包括 44 次插入17 次删除
  1. 13 1
      include/sound/core.h
  2. 31 16
      sound/core/init.c

+ 13 - 1
include/sound/core.h

@@ -296,8 +296,20 @@ int snd_card_locked(int card);
 extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
 extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
 #endif
 #endif
 
 
+int snd_card_create(int idx, const char *id,
+		    struct module *module, int extra_size,
+		    struct snd_card **card_ret);
+
+static inline __deprecated
 struct snd_card *snd_card_new(int idx, const char *id,
 struct snd_card *snd_card_new(int idx, const char *id,
-			 struct module *module, int extra_size);
+			      struct module *module, int extra_size)
+{
+	struct snd_card *card;
+	if (snd_card_create(idx, id, module, extra_size, &card) < 0)
+		return NULL;
+	return card;
+}
+
 int snd_card_disconnect(struct snd_card *card);
 int snd_card_disconnect(struct snd_card *card);
 int snd_card_free(struct snd_card *card);
 int snd_card_free(struct snd_card *card);
 int snd_card_free_when_closed(struct snd_card *card);
 int snd_card_free_when_closed(struct snd_card *card);

+ 31 - 16
sound/core/init.c

@@ -121,31 +121,44 @@ static inline int init_info_for_card(struct snd_card *card)
 #endif
 #endif
 
 
 /**
 /**
- *  snd_card_new - create and initialize a soundcard structure
+ *  snd_card_create - create and initialize a soundcard structure
  *  @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
  *  @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
  *  @xid: card identification (ASCII string)
  *  @xid: card identification (ASCII string)
  *  @module: top level module for locking
  *  @module: top level module for locking
  *  @extra_size: allocate this extra size after the main soundcard structure
  *  @extra_size: allocate this extra size after the main soundcard structure
+ *  @card_ret: the pointer to store the created card instance
  *
  *
  *  Creates and initializes a soundcard structure.
  *  Creates and initializes a soundcard structure.
  *
  *
- *  Returns kmallocated snd_card structure. Creates the ALSA control interface
- *  (which is blocked until snd_card_register function is called).
+ *  The function allocates snd_card instance via kzalloc with the given
+ *  space for the driver to use freely.  The allocated struct is stored
+ *  in the given card_ret pointer.
+ *
+ *  Returns zero if successful or a negative error code.
  */
  */
-struct snd_card *snd_card_new(int idx, const char *xid,
-			 struct module *module, int extra_size)
+int snd_card_create(int idx, const char *xid,
+		    struct module *module, int extra_size,
+		    struct snd_card **card_ret)
 {
 {
 	struct snd_card *card;
 	struct snd_card *card;
 	int err, idx2;
 	int err, idx2;
 
 
+	if (snd_BUG_ON(!card_ret))
+		return -EINVAL;
+	*card_ret = NULL;
+
 	if (extra_size < 0)
 	if (extra_size < 0)
 		extra_size = 0;
 		extra_size = 0;
 	card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
 	card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
-	if (card == NULL)
-		return NULL;
+	if (!card)
+		return -ENOMEM;
 	if (xid) {
 	if (xid) {
-		if (!snd_info_check_reserved_words(xid))
+		if (!snd_info_check_reserved_words(xid)) {
+			snd_printk(KERN_ERR
+				   "given id string '%s' is reserved.\n", xid);
+			err = -EBUSY;
 			goto __error;
 			goto __error;
+		}
 		strlcpy(card->id, xid, sizeof(card->id));
 		strlcpy(card->id, xid, sizeof(card->id));
 	}
 	}
 	err = 0;
 	err = 0;
@@ -202,26 +215,28 @@ struct snd_card *snd_card_new(int idx, const char *xid,
 #endif
 #endif
 	/* the control interface cannot be accessed from the user space until */
 	/* the control interface cannot be accessed from the user space until */
 	/* snd_cards_bitmask and snd_cards are set with snd_card_register */
 	/* snd_cards_bitmask and snd_cards are set with snd_card_register */
-	if ((err = snd_ctl_create(card)) < 0) {
-		snd_printd("unable to register control minors\n");
+	err = snd_ctl_create(card);
+	if (err < 0) {
+		snd_printk(KERN_ERR "unable to register control minors\n");
 		goto __error;
 		goto __error;
 	}
 	}
-	if ((err = snd_info_card_create(card)) < 0) {
-		snd_printd("unable to create card info\n");
+	err = snd_info_card_create(card);
+	if (err < 0) {
+		snd_printk(KERN_ERR "unable to create card info\n");
 		goto __error_ctl;
 		goto __error_ctl;
 	}
 	}
 	if (extra_size > 0)
 	if (extra_size > 0)
 		card->private_data = (char *)card + sizeof(struct snd_card);
 		card->private_data = (char *)card + sizeof(struct snd_card);
-	return card;
+	*card_ret = card;
+	return 0;
 
 
       __error_ctl:
       __error_ctl:
 	snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
 	snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
       __error:
       __error:
 	kfree(card);
 	kfree(card);
-      	return NULL;
+  	return err;
 }
 }
-
-EXPORT_SYMBOL(snd_card_new);
+EXPORT_SYMBOL(snd_card_create);
 
 
 /* return non-zero if a card is already locked */
 /* return non-zero if a card is already locked */
 int snd_card_locked(int card)
 int snd_card_locked(int card)