浏览代码

sdio: store vendor strings

Store vendor strings found in CISTPL_VERS_1 so that function drivers
can access them.

Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Pierre Ossman 17 年之前
父节点
当前提交
759bdc7af4
共有 5 个文件被更改,包括 60 次插入1 次删除
  1. 3 0
      drivers/mmc/core/bus.c
  2. 3 0
      drivers/mmc/core/sdio_bus.c
  3. 49 1
      drivers/mmc/core/sdio_cis.c
  4. 2 0
      include/linux/mmc/card.h
  5. 3 0
      include/linux/mmc/sdio_func.h

+ 3 - 0
drivers/mmc/core/bus.c

@@ -187,6 +187,9 @@ static void mmc_release_card(struct device *dev)
 
 	sdio_free_common_cis(card);
 
+	if (card->info)
+		kfree(card->info);
+
 	kfree(card);
 }
 

+ 3 - 0
drivers/mmc/core/sdio_bus.c

@@ -211,6 +211,9 @@ static void sdio_release_func(struct device *dev)
 
 	sdio_free_func_cis(func);
 
+	if (func->info)
+		kfree(func->info);
+
 	kfree(func);
 }
 

+ 49 - 1
drivers/mmc/core/sdio_cis.c

@@ -23,6 +23,54 @@
 #include "sdio_cis.h"
 #include "sdio_ops.h"
 
+static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
+			 const unsigned char *buf, unsigned size)
+{
+	unsigned i, nr_strings;
+	char **buffer, *string;
+
+	buf += 2;
+	size -= 2;
+
+	nr_strings = 0;
+	for (i = 0; i < size; i++) {
+		if (buf[i] == 0xff)
+			break;
+		if (buf[i] == 0)
+			nr_strings++;
+	}
+
+	if (buf[i-1] != '\0') {
+		printk(KERN_WARNING "SDIO: ignoring broken CISTPL_VERS_1\n");
+		return 0;
+	}
+
+	size = i;
+
+	buffer = kzalloc(sizeof(char*) * nr_strings + size, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	string = (char*)(buffer + nr_strings);
+
+	for (i = 0; i < nr_strings; i++) {
+		buffer[i] = string;
+		strcpy(string, buf);
+		string += strlen(string) + 1;
+		buf += strlen(buf) + 1;
+	}
+
+	if (func) {
+		func->num_info = nr_strings;
+		func->info = (const char**)buffer;
+	} else {
+		card->num_info = nr_strings;
+		card->info = (const char**)buffer;
+	}
+
+	return 0;
+}
+
 static int cistpl_manfid(struct mmc_card *card, struct sdio_func *func,
 			 const unsigned char *buf, unsigned size)
 {
@@ -119,7 +167,7 @@ struct cis_tpl {
 };
 
 static const struct cis_tpl cis_tpl_list[] = {
-	{	0x15,	3,	/* cistpl_vers_1 */	},
+	{	0x15,	3,	cistpl_vers_1		},
 	{	0x20,	4,	cistpl_manfid		},
 	{	0x21,	2,	/* cistpl_funcid */	},
 	{	0x22,	0,	cistpl_funce		},

+ 2 - 0
include/linux/mmc/card.h

@@ -108,6 +108,8 @@ struct mmc_card {
 	struct sdio_cccr	cccr;		/* common card info */
 	struct sdio_cis		cis;		/* common tuple info */
 	struct sdio_func	*sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
+	unsigned		num_info;	/* number of info strings */
+	const char		**info;		/* info strings */
 	struct sdio_func_tuple	*tuples;	/* unknown common tuples */
 };
 

+ 3 - 0
include/linux/mmc/sdio_func.h

@@ -51,6 +51,9 @@ struct sdio_func {
 
 	u8			tmpbuf[4];	/* DMA:able scratch buffer */
 
+	unsigned		num_info;	/* number of info strings */
+	const char		**info;		/* info strings */
+
 	struct sdio_func_tuple *tuples;
 };