1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * linux/drivers/mmc/core/sdio_cis.c 4 * 5 * Author: Nicolas Pitre 6 * Created: June 11, 2007 7 * Copyright: MontaVista Software Inc. 8 * 9 * Copyright 2007 Pierre Ossman 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/slab.h> 14 15 #include <linux/mmc/host.h> 16 #include <linux/mmc/card.h> 17 #include <linux/mmc/sdio.h> 18 #include <linux/mmc/sdio_func.h> 19 20 #include "sdio_cis.h" 21 #include "sdio_ops.h" 22 23 #define SDIO_READ_CIS_TIMEOUT_MS (10 * 1000) /* 10s */ 24 25 static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func, 26 const unsigned char *buf, unsigned size) 27 { 28 u8 major_rev, minor_rev; 29 unsigned i, nr_strings; 30 char **buffer, *string; 31 32 if (size < 2) 33 return 0; 34 35 major_rev = buf[0]; 36 minor_rev = buf[1]; 37 38 /* Find all null-terminated (including zero length) strings in 39 the TPLLV1_INFO field. Trailing garbage is ignored. */ 40 buf += 2; 41 size -= 2; 42 43 nr_strings = 0; 44 for (i = 0; i < size; i++) { 45 if (buf[i] == 0xff) 46 break; 47 if (buf[i] == 0) 48 nr_strings++; 49 } 50 if (nr_strings == 0) 51 return 0; 52 53 size = i; 54 55 buffer = kzalloc(sizeof(char*) * nr_strings + size, GFP_KERNEL); 56 if (!buffer) 57 return -ENOMEM; 58 59 string = (char*)(buffer + nr_strings); 60 memcpy(string, buf, size); 61 62 for (i = 0; i < nr_strings; i++) { 63 buffer[i] = string; 64 string = strchr(string, 0) + 1; 65 } 66 67 if (func) { 68 func->major_rev = major_rev; 69 func->minor_rev = minor_rev; 70 func->num_info = nr_strings; 71 func->info = (const char**)buffer; 72 } else { 73 card->major_rev = major_rev; 74 card->minor_rev = minor_rev; 75 card->num_info = nr_strings; 76 card->info = (const char**)buffer; 77 } 78 79 return 0; 80 } 81 82 static int cistpl_manfid(struct mmc_card *card, struct sdio_func *func, 83 const unsigned char *buf, unsigned size) 84 { 85 unsigned int vendor, device; 86 87 /* TPLMID_MANF */ 88 vendor = buf[0] | (buf[1] << 8); 89 90 /* TPLMID_CARD */ 91 device = buf[2] | (buf[3] << 8); 92 93 if (func) { 94 func->vendor = vendor; 95 func->device = device; 96 } else { 97 card->cis.vendor = vendor; 98 card->cis.device = device; 99 } 100 101 return 0; 102 } 103 104 static const unsigned char speed_val[16] = 105 { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; 106 static const unsigned int speed_unit[8] = 107 { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 }; 108 109 110 typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *, 111 const unsigned char *, unsigned); 112 113 struct cis_tpl { 114 unsigned char code; 115 unsigned char min_size; 116 tpl_parse_t *parse; 117 }; 118 119 static int cis_tpl_parse(struct mmc_card *card, struct sdio_func *func, 120 const char *tpl_descr, 121 const struct cis_tpl *tpl, int tpl_count, 122 unsigned char code, 123 const unsigned char *buf, unsigned size) 124 { 125 int i, ret; 126 127 /* look for a matching code in the table */ 128 for (i = 0; i < tpl_count; i++, tpl++) { 129 if (tpl->code == code) 130 break; 131 } 132 if (i < tpl_count) { 133 if (size >= tpl->min_size) { 134 if (tpl->parse) 135 ret = tpl->parse(card, func, buf, size); 136 else 137 ret = -EILSEQ; /* known tuple, not parsed */ 138 } else { 139 /* invalid tuple */ 140 ret = -EINVAL; 141 } 142 if (ret && ret != -EILSEQ && ret != -ENOENT) { 143 pr_err("%s: bad %s tuple 0x%02x (%u bytes)\n", 144 mmc_hostname(card->host), tpl_descr, code, size); 145 } 146 } else { 147 /* unknown tuple */ 148 ret = -ENOENT; 149 } 150 151 return ret; 152 } 153 154 static int cistpl_funce_common(struct mmc_card *card, struct sdio_func *func, 155 const unsigned char *buf, unsigned size) 156 { 157 /* Only valid for the common CIS (function 0) */ 158 if (func) 159 return -EINVAL; 160 161 /* TPLFE_FN0_BLK_SIZE */ 162 card->cis.blksize = buf[1] | (buf[2] << 8); 163 164 /* TPLFE_MAX_TRAN_SPEED */ 165 card->cis.max_dtr = speed_val[(buf[3] >> 3) & 15] * 166 speed_unit[buf[3] & 7]; 167 168 return 0; 169 } 170 171 static int cistpl_funce_func(struct mmc_card *card, struct sdio_func *func, 172 const unsigned char *buf, unsigned size) 173 { 174 unsigned vsn; 175 unsigned min_size; 176 177 /* Only valid for the individual function's CIS (1-7) */ 178 if (!func) 179 return -EINVAL; 180 181 /* 182 * This tuple has a different length depending on the SDIO spec 183 * version. 184 */ 185 vsn = func->card->cccr.sdio_vsn; 186 min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42; 187 188 if (size == 28 && vsn == SDIO_SDIO_REV_1_10) { 189 pr_warn("%s: card has broken SDIO 1.1 CIS, forcing SDIO 1.0\n", 190 mmc_hostname(card->host)); 191 vsn = SDIO_SDIO_REV_1_00; 192 } else if (size < min_size) { 193 return -EINVAL; 194 } 195 196 /* TPLFE_MAX_BLK_SIZE */ 197 func->max_blksize = buf[12] | (buf[13] << 8); 198 199 /* TPLFE_ENABLE_TIMEOUT_VAL, present in ver 1.1 and above */ 200 if (vsn > SDIO_SDIO_REV_1_00) 201 func->enable_timeout = (buf[28] | (buf[29] << 8)) * 10; 202 else 203 func->enable_timeout = jiffies_to_msecs(HZ); 204 205 return 0; 206 } 207 208 /* 209 * Known TPLFE_TYPEs table for CISTPL_FUNCE tuples. 210 * 211 * Note that, unlike PCMCIA, CISTPL_FUNCE tuples are not parsed depending 212 * on the TPLFID_FUNCTION value of the previous CISTPL_FUNCID as on SDIO 213 * TPLFID_FUNCTION is always hardcoded to 0x0C. 214 */ 215 static const struct cis_tpl cis_tpl_funce_list[] = { 216 { 0x00, 4, cistpl_funce_common }, 217 { 0x01, 0, cistpl_funce_func }, 218 { 0x04, 1+1+6, /* CISTPL_FUNCE_LAN_NODE_ID */ }, 219 }; 220 221 static int cistpl_funce(struct mmc_card *card, struct sdio_func *func, 222 const unsigned char *buf, unsigned size) 223 { 224 if (size < 1) 225 return -EINVAL; 226 227 return cis_tpl_parse(card, func, "CISTPL_FUNCE", 228 cis_tpl_funce_list, 229 ARRAY_SIZE(cis_tpl_funce_list), 230 buf[0], buf, size); 231 } 232 233 /* Known TPL_CODEs table for CIS tuples */ 234 static const struct cis_tpl cis_tpl_list[] = { 235 { 0x15, 3, cistpl_vers_1 }, 236 { 0x20, 4, cistpl_manfid }, 237 { 0x21, 2, /* cistpl_funcid */ }, 238 { 0x22, 0, cistpl_funce }, 239 { 0x91, 2, /* cistpl_sdio_std */ }, 240 }; 241 242 static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) 243 { 244 int ret; 245 struct sdio_func_tuple *this, **prev; 246 unsigned i, ptr = 0; 247 248 /* 249 * Note that this works for the common CIS (function number 0) as 250 * well as a function's CIS * since SDIO_CCCR_CIS and SDIO_FBR_CIS 251 * have the same offset. 252 */ 253 for (i = 0; i < 3; i++) { 254 unsigned char x, fn; 255 256 if (func) 257 fn = func->num; 258 else 259 fn = 0; 260 261 ret = mmc_io_rw_direct(card, 0, 0, 262 SDIO_FBR_BASE(fn) + SDIO_FBR_CIS + i, 0, &x); 263 if (ret) 264 return ret; 265 ptr |= x << (i * 8); 266 } 267 268 if (func) 269 prev = &func->tuples; 270 else 271 prev = &card->tuples; 272 273 if (*prev) 274 return -EINVAL; 275 276 do { 277 unsigned char tpl_code, tpl_link; 278 unsigned long timeout = jiffies + 279 msecs_to_jiffies(SDIO_READ_CIS_TIMEOUT_MS); 280 281 ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code); 282 if (ret) 283 break; 284 285 /* 0xff means we're done */ 286 if (tpl_code == 0xff) 287 break; 288 289 /* null entries have no link field or data */ 290 if (tpl_code == 0x00) 291 continue; 292 293 ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link); 294 if (ret) 295 break; 296 297 /* a size of 0xff also means we're done */ 298 if (tpl_link == 0xff) 299 break; 300 301 this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL); 302 if (!this) 303 return -ENOMEM; 304 305 for (i = 0; i < tpl_link; i++) { 306 ret = mmc_io_rw_direct(card, 0, 0, 307 ptr + i, 0, &this->data[i]); 308 if (ret) 309 break; 310 } 311 if (ret) { 312 kfree(this); 313 break; 314 } 315 316 /* Try to parse the CIS tuple */ 317 ret = cis_tpl_parse(card, func, "CIS", 318 cis_tpl_list, ARRAY_SIZE(cis_tpl_list), 319 tpl_code, this->data, tpl_link); 320 if (ret == -EILSEQ || ret == -ENOENT) { 321 /* 322 * The tuple is unknown or known but not parsed. 323 * Queue the tuple for the function driver. 324 */ 325 this->next = NULL; 326 this->code = tpl_code; 327 this->size = tpl_link; 328 *prev = this; 329 prev = &this->next; 330 331 if (ret == -ENOENT) { 332 333 if (time_after(jiffies, timeout)) 334 break; 335 336 #define FMT(type) "%s: queuing " type " CIS tuple 0x%02x [%*ph] (%u bytes)\n" 337 /* 338 * Tuples in this range are reserved for 339 * vendors, so don't warn about them 340 */ 341 if (tpl_code >= 0x80 && tpl_code <= 0x8f) 342 pr_debug_ratelimited(FMT("vendor"), 343 mmc_hostname(card->host), 344 tpl_code, tpl_link, this->data, 345 tpl_link); 346 else 347 pr_warn_ratelimited(FMT("unknown"), 348 mmc_hostname(card->host), 349 tpl_code, tpl_link, this->data, 350 tpl_link); 351 } 352 353 /* keep on analyzing tuples */ 354 ret = 0; 355 } else { 356 /* 357 * We don't need the tuple anymore if it was 358 * successfully parsed by the SDIO core or if it is 359 * not going to be queued for a driver. 360 */ 361 kfree(this); 362 } 363 364 ptr += tpl_link; 365 } while (!ret); 366 367 /* 368 * Link in all unknown tuples found in the common CIS so that 369 * drivers don't have to go digging in two places. 370 */ 371 if (func) 372 *prev = card->tuples; 373 374 return ret; 375 } 376 377 int sdio_read_common_cis(struct mmc_card *card) 378 { 379 return sdio_read_cis(card, NULL); 380 } 381 382 void sdio_free_common_cis(struct mmc_card *card) 383 { 384 struct sdio_func_tuple *tuple, *victim; 385 386 tuple = card->tuples; 387 388 while (tuple) { 389 victim = tuple; 390 tuple = tuple->next; 391 kfree(victim); 392 } 393 394 card->tuples = NULL; 395 } 396 397 int sdio_read_func_cis(struct sdio_func *func) 398 { 399 int ret; 400 401 ret = sdio_read_cis(func->card, func); 402 if (ret) 403 return ret; 404 405 /* 406 * Vendor/device id is optional for function CIS, so 407 * copy it from the card structure as needed. 408 */ 409 if (func->vendor == 0) { 410 func->vendor = func->card->cis.vendor; 411 func->device = func->card->cis.device; 412 } 413 414 return 0; 415 } 416 417 void sdio_free_func_cis(struct sdio_func *func) 418 { 419 struct sdio_func_tuple *tuple, *victim; 420 421 tuple = func->tuples; 422 423 while (tuple && tuple != func->card->tuples) { 424 victim = tuple; 425 tuple = tuple->next; 426 kfree(victim); 427 } 428 429 func->tuples = NULL; 430 } 431 432