Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * linux/drivers/mmc/core/sdio_cis.c
0004  *
0005  * Author:  Nicolas Pitre
0006  * Created: June 11, 2007
0007  * Copyright:   MontaVista Software Inc.
0008  *
0009  * Copyright 2007 Pierre Ossman
0010  */
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/slab.h>
0014 
0015 #include <linux/mmc/host.h>
0016 #include <linux/mmc/card.h>
0017 #include <linux/mmc/sdio.h>
0018 #include <linux/mmc/sdio_func.h>
0019 
0020 #include "sdio_cis.h"
0021 #include "sdio_ops.h"
0022 
0023 #define SDIO_READ_CIS_TIMEOUT_MS  (10 * 1000) /* 10s */
0024 
0025 static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
0026              const unsigned char *buf, unsigned size)
0027 {
0028     u8 major_rev, minor_rev;
0029     unsigned i, nr_strings;
0030     char **buffer, *string;
0031 
0032     if (size < 2)
0033         return 0;
0034 
0035     major_rev = buf[0];
0036     minor_rev = buf[1];
0037 
0038     /* Find all null-terminated (including zero length) strings in
0039        the TPLLV1_INFO field. Trailing garbage is ignored. */
0040     buf += 2;
0041     size -= 2;
0042 
0043     nr_strings = 0;
0044     for (i = 0; i < size; i++) {
0045         if (buf[i] == 0xff)
0046             break;
0047         if (buf[i] == 0)
0048             nr_strings++;
0049     }
0050     if (nr_strings == 0)
0051         return 0;
0052 
0053     size = i;
0054 
0055     buffer = kzalloc(sizeof(char*) * nr_strings + size, GFP_KERNEL);
0056     if (!buffer)
0057         return -ENOMEM;
0058 
0059     string = (char*)(buffer + nr_strings);
0060 
0061     for (i = 0; i < nr_strings; i++) {
0062         buffer[i] = string;
0063         strcpy(string, buf);
0064         string += strlen(string) + 1;
0065         buf += strlen(buf) + 1;
0066     }
0067 
0068     if (func) {
0069         func->major_rev = major_rev;
0070         func->minor_rev = minor_rev;
0071         func->num_info = nr_strings;
0072         func->info = (const char**)buffer;
0073     } else {
0074         card->major_rev = major_rev;
0075         card->minor_rev = minor_rev;
0076         card->num_info = nr_strings;
0077         card->info = (const char**)buffer;
0078     }
0079 
0080     return 0;
0081 }
0082 
0083 static int cistpl_manfid(struct mmc_card *card, struct sdio_func *func,
0084              const unsigned char *buf, unsigned size)
0085 {
0086     unsigned int vendor, device;
0087 
0088     /* TPLMID_MANF */
0089     vendor = buf[0] | (buf[1] << 8);
0090 
0091     /* TPLMID_CARD */
0092     device = buf[2] | (buf[3] << 8);
0093 
0094     if (func) {
0095         func->vendor = vendor;
0096         func->device = device;
0097     } else {
0098         card->cis.vendor = vendor;
0099         card->cis.device = device;
0100     }
0101 
0102     return 0;
0103 }
0104 
0105 static const unsigned char speed_val[16] =
0106     { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
0107 static const unsigned int speed_unit[8] =
0108     { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
0109 
0110 
0111 typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
0112                const unsigned char *, unsigned);
0113 
0114 struct cis_tpl {
0115     unsigned char code;
0116     unsigned char min_size;
0117     tpl_parse_t *parse;
0118 };
0119 
0120 static int cis_tpl_parse(struct mmc_card *card, struct sdio_func *func,
0121              const char *tpl_descr,
0122              const struct cis_tpl *tpl, int tpl_count,
0123              unsigned char code,
0124              const unsigned char *buf, unsigned size)
0125 {
0126     int i, ret;
0127 
0128     /* look for a matching code in the table */
0129     for (i = 0; i < tpl_count; i++, tpl++) {
0130         if (tpl->code == code)
0131             break;
0132     }
0133     if (i < tpl_count) {
0134         if (size >= tpl->min_size) {
0135             if (tpl->parse)
0136                 ret = tpl->parse(card, func, buf, size);
0137             else
0138                 ret = -EILSEQ;  /* known tuple, not parsed */
0139         } else {
0140             /* invalid tuple */
0141             ret = -EINVAL;
0142         }
0143         if (ret && ret != -EILSEQ && ret != -ENOENT) {
0144             pr_err("%s: bad %s tuple 0x%02x (%u bytes)\n",
0145                    mmc_hostname(card->host), tpl_descr, code, size);
0146         }
0147     } else {
0148         /* unknown tuple */
0149         ret = -ENOENT;
0150     }
0151 
0152     return ret;
0153 }
0154 
0155 static int cistpl_funce_common(struct mmc_card *card, struct sdio_func *func,
0156                    const unsigned char *buf, unsigned size)
0157 {
0158     /* Only valid for the common CIS (function 0) */
0159     if (func)
0160         return -EINVAL;
0161 
0162     /* TPLFE_FN0_BLK_SIZE */
0163     card->cis.blksize = buf[1] | (buf[2] << 8);
0164 
0165     /* TPLFE_MAX_TRAN_SPEED */
0166     card->cis.max_dtr = speed_val[(buf[3] >> 3) & 15] *
0167                 speed_unit[buf[3] & 7];
0168 
0169     return 0;
0170 }
0171 
0172 static int cistpl_funce_func(struct mmc_card *card, struct sdio_func *func,
0173                  const unsigned char *buf, unsigned size)
0174 {
0175     unsigned vsn;
0176     unsigned min_size;
0177 
0178     /* Only valid for the individual function's CIS (1-7) */
0179     if (!func)
0180         return -EINVAL;
0181 
0182     /*
0183      * This tuple has a different length depending on the SDIO spec
0184      * version.
0185      */
0186     vsn = func->card->cccr.sdio_vsn;
0187     min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
0188 
0189     if (size == 28 && vsn == SDIO_SDIO_REV_1_10) {
0190         pr_warn("%s: card has broken SDIO 1.1 CIS, forcing SDIO 1.0\n",
0191             mmc_hostname(card->host));
0192         vsn = SDIO_SDIO_REV_1_00;
0193     } else if (size < min_size) {
0194         return -EINVAL;
0195     }
0196 
0197     /* TPLFE_MAX_BLK_SIZE */
0198     func->max_blksize = buf[12] | (buf[13] << 8);
0199 
0200     /* TPLFE_ENABLE_TIMEOUT_VAL, present in ver 1.1 and above */
0201     if (vsn > SDIO_SDIO_REV_1_00)
0202         func->enable_timeout = (buf[28] | (buf[29] << 8)) * 10;
0203     else
0204         func->enable_timeout = jiffies_to_msecs(HZ);
0205 
0206     return 0;
0207 }
0208 
0209 /*
0210  * Known TPLFE_TYPEs table for CISTPL_FUNCE tuples.
0211  *
0212  * Note that, unlike PCMCIA, CISTPL_FUNCE tuples are not parsed depending
0213  * on the TPLFID_FUNCTION value of the previous CISTPL_FUNCID as on SDIO
0214  * TPLFID_FUNCTION is always hardcoded to 0x0C.
0215  */
0216 static const struct cis_tpl cis_tpl_funce_list[] = {
0217     {   0x00,   4,  cistpl_funce_common     },
0218     {   0x01,   0,  cistpl_funce_func       },
0219     {   0x04,   1+1+6,  /* CISTPL_FUNCE_LAN_NODE_ID */  },
0220 };
0221 
0222 static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
0223             const unsigned char *buf, unsigned size)
0224 {
0225     if (size < 1)
0226         return -EINVAL;
0227 
0228     return cis_tpl_parse(card, func, "CISTPL_FUNCE",
0229                  cis_tpl_funce_list,
0230                  ARRAY_SIZE(cis_tpl_funce_list),
0231                  buf[0], buf, size);
0232 }
0233 
0234 /* Known TPL_CODEs table for CIS tuples */
0235 static const struct cis_tpl cis_tpl_list[] = {
0236     {   0x15,   3,  cistpl_vers_1       },
0237     {   0x20,   4,  cistpl_manfid       },
0238     {   0x21,   2,  /* cistpl_funcid */ },
0239     {   0x22,   0,  cistpl_funce        },
0240     {   0x91,   2,  /* cistpl_sdio_std */   },
0241 };
0242 
0243 static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
0244 {
0245     int ret;
0246     struct sdio_func_tuple *this, **prev;
0247     unsigned i, ptr = 0;
0248 
0249     /*
0250      * Note that this works for the common CIS (function number 0) as
0251      * well as a function's CIS * since SDIO_CCCR_CIS and SDIO_FBR_CIS
0252      * have the same offset.
0253      */
0254     for (i = 0; i < 3; i++) {
0255         unsigned char x, fn;
0256 
0257         if (func)
0258             fn = func->num;
0259         else
0260             fn = 0;
0261 
0262         ret = mmc_io_rw_direct(card, 0, 0,
0263             SDIO_FBR_BASE(fn) + SDIO_FBR_CIS + i, 0, &x);
0264         if (ret)
0265             return ret;
0266         ptr |= x << (i * 8);
0267     }
0268 
0269     if (func)
0270         prev = &func->tuples;
0271     else
0272         prev = &card->tuples;
0273 
0274     if (*prev)
0275         return -EINVAL;
0276 
0277     do {
0278         unsigned char tpl_code, tpl_link;
0279         unsigned long timeout = jiffies +
0280             msecs_to_jiffies(SDIO_READ_CIS_TIMEOUT_MS);
0281 
0282         ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code);
0283         if (ret)
0284             break;
0285 
0286         /* 0xff means we're done */
0287         if (tpl_code == 0xff)
0288             break;
0289 
0290         /* null entries have no link field or data */
0291         if (tpl_code == 0x00)
0292             continue;
0293 
0294         ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link);
0295         if (ret)
0296             break;
0297 
0298         /* a size of 0xff also means we're done */
0299         if (tpl_link == 0xff)
0300             break;
0301 
0302         this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL);
0303         if (!this)
0304             return -ENOMEM;
0305 
0306         for (i = 0; i < tpl_link; i++) {
0307             ret = mmc_io_rw_direct(card, 0, 0,
0308                            ptr + i, 0, &this->data[i]);
0309             if (ret)
0310                 break;
0311         }
0312         if (ret) {
0313             kfree(this);
0314             break;
0315         }
0316 
0317         /* Try to parse the CIS tuple */
0318         ret = cis_tpl_parse(card, func, "CIS",
0319                     cis_tpl_list, ARRAY_SIZE(cis_tpl_list),
0320                     tpl_code, this->data, tpl_link);
0321         if (ret == -EILSEQ || ret == -ENOENT) {
0322             /*
0323              * The tuple is unknown or known but not parsed.
0324              * Queue the tuple for the function driver.
0325              */
0326             this->next = NULL;
0327             this->code = tpl_code;
0328             this->size = tpl_link;
0329             *prev = this;
0330             prev = &this->next;
0331 
0332             if (ret == -ENOENT) {
0333 
0334                 if (time_after(jiffies, timeout))
0335                     break;
0336 
0337 #define FMT(type) "%s: queuing " type " CIS tuple 0x%02x [%*ph] (%u bytes)\n"
0338                 /*
0339                  * Tuples in this range are reserved for
0340                  * vendors, so don't warn about them
0341                  */
0342                 if (tpl_code >= 0x80 && tpl_code <= 0x8f)
0343                     pr_debug_ratelimited(FMT("vendor"),
0344                         mmc_hostname(card->host),
0345                         tpl_code, tpl_link, this->data,
0346                         tpl_link);
0347                 else
0348                     pr_warn_ratelimited(FMT("unknown"),
0349                         mmc_hostname(card->host),
0350                         tpl_code, tpl_link, this->data,
0351                         tpl_link);
0352             }
0353 
0354             /* keep on analyzing tuples */
0355             ret = 0;
0356         } else {
0357             /*
0358              * We don't need the tuple anymore if it was
0359              * successfully parsed by the SDIO core or if it is
0360              * not going to be queued for a driver.
0361              */
0362             kfree(this);
0363         }
0364 
0365         ptr += tpl_link;
0366     } while (!ret);
0367 
0368     /*
0369      * Link in all unknown tuples found in the common CIS so that
0370      * drivers don't have to go digging in two places.
0371      */
0372     if (func)
0373         *prev = card->tuples;
0374 
0375     return ret;
0376 }
0377 
0378 int sdio_read_common_cis(struct mmc_card *card)
0379 {
0380     return sdio_read_cis(card, NULL);
0381 }
0382 
0383 void sdio_free_common_cis(struct mmc_card *card)
0384 {
0385     struct sdio_func_tuple *tuple, *victim;
0386 
0387     tuple = card->tuples;
0388 
0389     while (tuple) {
0390         victim = tuple;
0391         tuple = tuple->next;
0392         kfree(victim);
0393     }
0394 
0395     card->tuples = NULL;
0396 }
0397 
0398 int sdio_read_func_cis(struct sdio_func *func)
0399 {
0400     int ret;
0401 
0402     ret = sdio_read_cis(func->card, func);
0403     if (ret)
0404         return ret;
0405 
0406     /*
0407      * Since we've linked to tuples in the card structure,
0408      * we must make sure we have a reference to it.
0409      */
0410     get_device(&func->card->dev);
0411 
0412     /*
0413      * Vendor/device id is optional for function CIS, so
0414      * copy it from the card structure as needed.
0415      */
0416     if (func->vendor == 0) {
0417         func->vendor = func->card->cis.vendor;
0418         func->device = func->card->cis.device;
0419     }
0420 
0421     return 0;
0422 }
0423 
0424 void sdio_free_func_cis(struct sdio_func *func)
0425 {
0426     struct sdio_func_tuple *tuple, *victim;
0427 
0428     tuple = func->tuples;
0429 
0430     while (tuple && tuple != func->card->tuples) {
0431         victim = tuple;
0432         tuple = tuple->next;
0433         kfree(victim);
0434     }
0435 
0436     func->tuples = NULL;
0437 
0438     /*
0439      * We have now removed the link to the tuples in the
0440      * card structure, so remove the reference.
0441      */
0442     put_device(&func->card->dev);
0443 }
0444