sdio: store vendor strings
authorPierre Ossman <drzeus@drzeus.cx>
Wed, 19 Sep 2007 16:42:16 +0000 (18:42 +0200)
committerPierre Ossman <drzeus@drzeus.cx>
Sun, 23 Sep 2007 19:28:01 +0000 (21:28 +0200)
Store vendor strings found in CISTPL_VERS_1 so that function drivers
can access them.

Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
drivers/mmc/core/bus.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/core/sdio_cis.c
include/linux/mmc/card.h
include/linux/mmc/sdio_func.h

index 1cc11714916f99c79e5fef1919f216319bfd0f02..733ac95331c733ce10e2ae27944d43375accc533 100644 (file)
@@ -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);
 }
 
index 683d91740109ebfe9a5b6bd22b2d96b7287cfab8..0713a8c71e54b2980d88127644e14cd9ed87f748 100644 (file)
@@ -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);
 }
 
index 1d03f12bbb38824002d90dee04533d916b0eecba..d5e51b1c7b3fb715ebc81dcad5468c572748d42e 100644 (file)
 #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            },
index a444431e28bd3cf489878e2362655255c08b209f..0d508ac17d6452b5a35429fd38704c8de2c13de4 100644 (file)
@@ -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 */
 };
 
index da6a96c39776e022726dd01810bf3787d489db6c..b050f4d7b41f05af47bf98c342c0b4528d110e19 100644 (file)
@@ -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;
 };