diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2010-08-13 19:59:15 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2010-08-13 19:59:15 -0400 |
commit | 7d72e6fa56c4100b9669efe0044f77ed9eb785a1 (patch) | |
tree | 5e90bf4969809a1ab20b97432b85be20ccfaa1f4 /drivers/mmc/core/sd.c | |
parent | ba00376b0b13f234d839541a7b36a5bf5c2a4036 (diff) | |
parent | 2be1f3a73dd02e38e181cf5abacb3d45a6a2d6b8 (diff) |
Merge branch 'master' into for-linus
Diffstat (limited to 'drivers/mmc/core/sd.c')
-rw-r--r-- | drivers/mmc/core/sd.c | 331 |
1 files changed, 227 insertions, 104 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 5eac21df4809..0f5241085557 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -59,7 +59,7 @@ static const unsigned int tacc_mant[] = { | |||
59 | /* | 59 | /* |
60 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | 60 | * Given the decoded CSD structure, decode the raw CID to our CID structure. |
61 | */ | 61 | */ |
62 | static void mmc_decode_cid(struct mmc_card *card) | 62 | void mmc_decode_cid(struct mmc_card *card) |
63 | { | 63 | { |
64 | u32 *resp = card->raw_cid; | 64 | u32 *resp = card->raw_cid; |
65 | 65 | ||
@@ -119,6 +119,13 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
119 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | 119 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); |
120 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | 120 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); |
121 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | 121 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); |
122 | |||
123 | if (UNSTUFF_BITS(resp, 46, 1)) { | ||
124 | csd->erase_size = 1; | ||
125 | } else if (csd->write_blkbits >= 9) { | ||
126 | csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1; | ||
127 | csd->erase_size <<= csd->write_blkbits - 9; | ||
128 | } | ||
122 | break; | 129 | break; |
123 | case 1: | 130 | case 1: |
124 | /* | 131 | /* |
@@ -147,6 +154,7 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
147 | csd->r2w_factor = 4; /* Unused */ | 154 | csd->r2w_factor = 4; /* Unused */ |
148 | csd->write_blkbits = 9; | 155 | csd->write_blkbits = 9; |
149 | csd->write_partial = 0; | 156 | csd->write_partial = 0; |
157 | csd->erase_size = 1; | ||
150 | break; | 158 | break; |
151 | default: | 159 | default: |
152 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", | 160 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", |
@@ -154,6 +162,8 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
154 | return -EINVAL; | 162 | return -EINVAL; |
155 | } | 163 | } |
156 | 164 | ||
165 | card->erase_size = csd->erase_size; | ||
166 | |||
157 | return 0; | 167 | return 0; |
158 | } | 168 | } |
159 | 169 | ||
@@ -179,10 +189,68 @@ static int mmc_decode_scr(struct mmc_card *card) | |||
179 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); | 189 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); |
180 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); | 190 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); |
181 | 191 | ||
192 | if (UNSTUFF_BITS(resp, 55, 1)) | ||
193 | card->erased_byte = 0xFF; | ||
194 | else | ||
195 | card->erased_byte = 0x0; | ||
196 | |||
182 | return 0; | 197 | return 0; |
183 | } | 198 | } |
184 | 199 | ||
185 | /* | 200 | /* |
201 | * Fetch and process SD Status register. | ||
202 | */ | ||
203 | static int mmc_read_ssr(struct mmc_card *card) | ||
204 | { | ||
205 | unsigned int au, es, et, eo; | ||
206 | int err, i; | ||
207 | u32 *ssr; | ||
208 | |||
209 | if (!(card->csd.cmdclass & CCC_APP_SPEC)) { | ||
210 | printk(KERN_WARNING "%s: card lacks mandatory SD Status " | ||
211 | "function.\n", mmc_hostname(card->host)); | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | ssr = kmalloc(64, GFP_KERNEL); | ||
216 | if (!ssr) | ||
217 | return -ENOMEM; | ||
218 | |||
219 | err = mmc_app_sd_status(card, ssr); | ||
220 | if (err) { | ||
221 | printk(KERN_WARNING "%s: problem reading SD Status " | ||
222 | "register.\n", mmc_hostname(card->host)); | ||
223 | err = 0; | ||
224 | goto out; | ||
225 | } | ||
226 | |||
227 | for (i = 0; i < 16; i++) | ||
228 | ssr[i] = be32_to_cpu(ssr[i]); | ||
229 | |||
230 | /* | ||
231 | * UNSTUFF_BITS only works with four u32s so we have to offset the | ||
232 | * bitfield positions accordingly. | ||
233 | */ | ||
234 | au = UNSTUFF_BITS(ssr, 428 - 384, 4); | ||
235 | if (au > 0 || au <= 9) { | ||
236 | card->ssr.au = 1 << (au + 4); | ||
237 | es = UNSTUFF_BITS(ssr, 408 - 384, 16); | ||
238 | et = UNSTUFF_BITS(ssr, 402 - 384, 6); | ||
239 | eo = UNSTUFF_BITS(ssr, 400 - 384, 2); | ||
240 | if (es && et) { | ||
241 | card->ssr.erase_timeout = (et * 1000) / es; | ||
242 | card->ssr.erase_offset = eo * 1000; | ||
243 | } | ||
244 | } else { | ||
245 | printk(KERN_WARNING "%s: SD Status: Invalid Allocation Unit " | ||
246 | "size.\n", mmc_hostname(card->host)); | ||
247 | } | ||
248 | out: | ||
249 | kfree(ssr); | ||
250 | return err; | ||
251 | } | ||
252 | |||
253 | /* | ||
186 | * Fetches and decodes switch information | 254 | * Fetches and decodes switch information |
187 | */ | 255 | */ |
188 | static int mmc_read_switch(struct mmc_card *card) | 256 | static int mmc_read_switch(struct mmc_card *card) |
@@ -238,7 +306,7 @@ out: | |||
238 | /* | 306 | /* |
239 | * Test if the card supports high-speed mode and, if so, switch to it. | 307 | * Test if the card supports high-speed mode and, if so, switch to it. |
240 | */ | 308 | */ |
241 | static int mmc_switch_hs(struct mmc_card *card) | 309 | int mmc_sd_switch_hs(struct mmc_card *card) |
242 | { | 310 | { |
243 | int err; | 311 | int err; |
244 | u8 *status; | 312 | u8 *status; |
@@ -272,9 +340,9 @@ static int mmc_switch_hs(struct mmc_card *card) | |||
272 | printk(KERN_WARNING "%s: Problem switching card " | 340 | printk(KERN_WARNING "%s: Problem switching card " |
273 | "into high-speed mode!\n", | 341 | "into high-speed mode!\n", |
274 | mmc_hostname(card->host)); | 342 | mmc_hostname(card->host)); |
343 | err = 0; | ||
275 | } else { | 344 | } else { |
276 | mmc_card_set_highspeed(card); | 345 | err = 1; |
277 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
278 | } | 346 | } |
279 | 347 | ||
280 | out: | 348 | out: |
@@ -289,6 +357,8 @@ MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | |||
289 | card->raw_csd[2], card->raw_csd[3]); | 357 | card->raw_csd[2], card->raw_csd[3]); |
290 | MMC_DEV_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); | 358 | MMC_DEV_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); |
291 | MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); | 359 | MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); |
360 | MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9); | ||
361 | MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9); | ||
292 | MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); | 362 | MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); |
293 | MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); | 363 | MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); |
294 | MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); | 364 | MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); |
@@ -302,6 +372,8 @@ static struct attribute *sd_std_attrs[] = { | |||
302 | &dev_attr_csd.attr, | 372 | &dev_attr_csd.attr, |
303 | &dev_attr_scr.attr, | 373 | &dev_attr_scr.attr, |
304 | &dev_attr_date.attr, | 374 | &dev_attr_date.attr, |
375 | &dev_attr_erase_size.attr, | ||
376 | &dev_attr_preferred_erase_size.attr, | ||
305 | &dev_attr_fwrev.attr, | 377 | &dev_attr_fwrev.attr, |
306 | &dev_attr_hwrev.attr, | 378 | &dev_attr_hwrev.attr, |
307 | &dev_attr_manfid.attr, | 379 | &dev_attr_manfid.attr, |
@@ -320,26 +392,16 @@ static const struct attribute_group *sd_attr_groups[] = { | |||
320 | NULL, | 392 | NULL, |
321 | }; | 393 | }; |
322 | 394 | ||
323 | static struct device_type sd_type = { | 395 | struct device_type sd_type = { |
324 | .groups = sd_attr_groups, | 396 | .groups = sd_attr_groups, |
325 | }; | 397 | }; |
326 | 398 | ||
327 | /* | 399 | /* |
328 | * Handle the detection and initialisation of a card. | 400 | * Fetch CID from card. |
329 | * | ||
330 | * In the case of a resume, "oldcard" will contain the card | ||
331 | * we're trying to reinitialise. | ||
332 | */ | 401 | */ |
333 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | 402 | int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) |
334 | struct mmc_card *oldcard) | ||
335 | { | 403 | { |
336 | struct mmc_card *card; | ||
337 | int err; | 404 | int err; |
338 | u32 cid[4]; | ||
339 | unsigned int max_dtr; | ||
340 | |||
341 | BUG_ON(!host); | ||
342 | WARN_ON(!host->claimed); | ||
343 | 405 | ||
344 | /* | 406 | /* |
345 | * Since we're changing the OCR value, we seem to | 407 | * Since we're changing the OCR value, we seem to |
@@ -361,92 +423,67 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
361 | 423 | ||
362 | err = mmc_send_app_op_cond(host, ocr, NULL); | 424 | err = mmc_send_app_op_cond(host, ocr, NULL); |
363 | if (err) | 425 | if (err) |
364 | goto err; | 426 | return err; |
365 | 427 | ||
366 | /* | ||
367 | * Fetch CID from card. | ||
368 | */ | ||
369 | if (mmc_host_is_spi(host)) | 428 | if (mmc_host_is_spi(host)) |
370 | err = mmc_send_cid(host, cid); | 429 | err = mmc_send_cid(host, cid); |
371 | else | 430 | else |
372 | err = mmc_all_send_cid(host, cid); | 431 | err = mmc_all_send_cid(host, cid); |
373 | if (err) | ||
374 | goto err; | ||
375 | 432 | ||
376 | if (oldcard) { | 433 | return err; |
377 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { | 434 | } |
378 | err = -ENOENT; | ||
379 | goto err; | ||
380 | } | ||
381 | |||
382 | card = oldcard; | ||
383 | } else { | ||
384 | /* | ||
385 | * Allocate card structure. | ||
386 | */ | ||
387 | card = mmc_alloc_card(host, &sd_type); | ||
388 | if (IS_ERR(card)) { | ||
389 | err = PTR_ERR(card); | ||
390 | goto err; | ||
391 | } | ||
392 | 435 | ||
393 | card->type = MMC_TYPE_SD; | 436 | int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card) |
394 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | 437 | { |
395 | } | 438 | int err; |
396 | 439 | ||
397 | /* | 440 | /* |
398 | * For native busses: get card RCA and quit open drain mode. | 441 | * Fetch CSD from card. |
399 | */ | 442 | */ |
400 | if (!mmc_host_is_spi(host)) { | 443 | err = mmc_send_csd(card, card->raw_csd); |
401 | err = mmc_send_relative_addr(host, &card->rca); | 444 | if (err) |
402 | if (err) | 445 | return err; |
403 | goto free_card; | ||
404 | 446 | ||
405 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | 447 | err = mmc_decode_csd(card); |
406 | } | 448 | if (err) |
449 | return err; | ||
407 | 450 | ||
408 | if (!oldcard) { | 451 | return 0; |
452 | } | ||
453 | |||
454 | int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, | ||
455 | bool reinit) | ||
456 | { | ||
457 | int err; | ||
458 | |||
459 | if (!reinit) { | ||
409 | /* | 460 | /* |
410 | * Fetch CSD from card. | 461 | * Fetch SCR from card. |
411 | */ | 462 | */ |
412 | err = mmc_send_csd(card, card->raw_csd); | 463 | err = mmc_app_send_scr(card, card->raw_scr); |
413 | if (err) | ||
414 | goto free_card; | ||
415 | |||
416 | err = mmc_decode_csd(card); | ||
417 | if (err) | 464 | if (err) |
418 | goto free_card; | 465 | return err; |
419 | |||
420 | mmc_decode_cid(card); | ||
421 | } | ||
422 | 466 | ||
423 | /* | 467 | err = mmc_decode_scr(card); |
424 | * Select card, as all following commands rely on that. | ||
425 | */ | ||
426 | if (!mmc_host_is_spi(host)) { | ||
427 | err = mmc_select_card(card); | ||
428 | if (err) | 468 | if (err) |
429 | goto free_card; | 469 | return err; |
430 | } | ||
431 | 470 | ||
432 | if (!oldcard) { | ||
433 | /* | 471 | /* |
434 | * Fetch SCR from card. | 472 | * Fetch and process SD Status register. |
435 | */ | 473 | */ |
436 | err = mmc_app_send_scr(card, card->raw_scr); | 474 | err = mmc_read_ssr(card); |
437 | if (err) | 475 | if (err) |
438 | goto free_card; | 476 | return err; |
439 | 477 | ||
440 | err = mmc_decode_scr(card); | 478 | /* Erase init depends on CSD and SSR */ |
441 | if (err < 0) | 479 | mmc_init_erase(card); |
442 | goto free_card; | ||
443 | 480 | ||
444 | /* | 481 | /* |
445 | * Fetch switch information from card. | 482 | * Fetch switch information from card. |
446 | */ | 483 | */ |
447 | err = mmc_read_switch(card); | 484 | err = mmc_read_switch(card); |
448 | if (err) | 485 | if (err) |
449 | goto free_card; | 486 | return err; |
450 | } | 487 | } |
451 | 488 | ||
452 | /* | 489 | /* |
@@ -458,20 +495,34 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
458 | if (mmc_host_is_spi(host)) { | 495 | if (mmc_host_is_spi(host)) { |
459 | err = mmc_spi_set_crc(host, use_spi_crc); | 496 | err = mmc_spi_set_crc(host, use_spi_crc); |
460 | if (err) | 497 | if (err) |
461 | goto free_card; | 498 | return err; |
462 | } | 499 | } |
463 | 500 | ||
464 | /* | 501 | /* |
465 | * Attempt to change to high-speed (if supported) | 502 | * Check if read-only switch is active. |
466 | */ | 503 | */ |
467 | err = mmc_switch_hs(card); | 504 | if (!reinit) { |
468 | if (err) | 505 | int ro = -1; |
469 | goto free_card; | ||
470 | 506 | ||
471 | /* | 507 | if (host->ops->get_ro) |
472 | * Compute bus speed. | 508 | ro = host->ops->get_ro(host); |
473 | */ | 509 | |
474 | max_dtr = (unsigned int)-1; | 510 | if (ro < 0) { |
511 | printk(KERN_WARNING "%s: host does not " | ||
512 | "support reading read-only " | ||
513 | "switch. assuming write-enable.\n", | ||
514 | mmc_hostname(host)); | ||
515 | } else if (ro > 0) { | ||
516 | mmc_card_set_readonly(card); | ||
517 | } | ||
518 | } | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | unsigned mmc_sd_get_max_clock(struct mmc_card *card) | ||
524 | { | ||
525 | unsigned max_dtr = (unsigned int)-1; | ||
475 | 526 | ||
476 | if (mmc_card_highspeed(card)) { | 527 | if (mmc_card_highspeed(card)) { |
477 | if (max_dtr > card->sw_caps.hs_max_dtr) | 528 | if (max_dtr > card->sw_caps.hs_max_dtr) |
@@ -480,7 +531,97 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
480 | max_dtr = card->csd.max_dtr; | 531 | max_dtr = card->csd.max_dtr; |
481 | } | 532 | } |
482 | 533 | ||
483 | mmc_set_clock(host, max_dtr); | 534 | return max_dtr; |
535 | } | ||
536 | |||
537 | void mmc_sd_go_highspeed(struct mmc_card *card) | ||
538 | { | ||
539 | mmc_card_set_highspeed(card); | ||
540 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
541 | } | ||
542 | |||
543 | /* | ||
544 | * Handle the detection and initialisation of a card. | ||
545 | * | ||
546 | * In the case of a resume, "oldcard" will contain the card | ||
547 | * we're trying to reinitialise. | ||
548 | */ | ||
549 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | ||
550 | struct mmc_card *oldcard) | ||
551 | { | ||
552 | struct mmc_card *card; | ||
553 | int err; | ||
554 | u32 cid[4]; | ||
555 | |||
556 | BUG_ON(!host); | ||
557 | WARN_ON(!host->claimed); | ||
558 | |||
559 | err = mmc_sd_get_cid(host, ocr, cid); | ||
560 | if (err) | ||
561 | return err; | ||
562 | |||
563 | if (oldcard) { | ||
564 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | ||
565 | return -ENOENT; | ||
566 | |||
567 | card = oldcard; | ||
568 | } else { | ||
569 | /* | ||
570 | * Allocate card structure. | ||
571 | */ | ||
572 | card = mmc_alloc_card(host, &sd_type); | ||
573 | if (IS_ERR(card)) | ||
574 | return PTR_ERR(card); | ||
575 | |||
576 | card->type = MMC_TYPE_SD; | ||
577 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | ||
578 | } | ||
579 | |||
580 | /* | ||
581 | * For native busses: get card RCA and quit open drain mode. | ||
582 | */ | ||
583 | if (!mmc_host_is_spi(host)) { | ||
584 | err = mmc_send_relative_addr(host, &card->rca); | ||
585 | if (err) | ||
586 | return err; | ||
587 | |||
588 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
589 | } | ||
590 | |||
591 | if (!oldcard) { | ||
592 | err = mmc_sd_get_csd(host, card); | ||
593 | if (err) | ||
594 | return err; | ||
595 | |||
596 | mmc_decode_cid(card); | ||
597 | } | ||
598 | |||
599 | /* | ||
600 | * Select card, as all following commands rely on that. | ||
601 | */ | ||
602 | if (!mmc_host_is_spi(host)) { | ||
603 | err = mmc_select_card(card); | ||
604 | if (err) | ||
605 | return err; | ||
606 | } | ||
607 | |||
608 | err = mmc_sd_setup_card(host, card, oldcard != NULL); | ||
609 | if (err) | ||
610 | goto free_card; | ||
611 | |||
612 | /* | ||
613 | * Attempt to change to high-speed (if supported) | ||
614 | */ | ||
615 | err = mmc_sd_switch_hs(card); | ||
616 | if (err > 0) | ||
617 | mmc_sd_go_highspeed(card); | ||
618 | else if (err) | ||
619 | goto free_card; | ||
620 | |||
621 | /* | ||
622 | * Set bus speed. | ||
623 | */ | ||
624 | mmc_set_clock(host, mmc_sd_get_max_clock(card)); | ||
484 | 625 | ||
485 | /* | 626 | /* |
486 | * Switch to wider bus (if supported). | 627 | * Switch to wider bus (if supported). |
@@ -494,30 +635,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
494 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | 635 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); |
495 | } | 636 | } |
496 | 637 | ||
497 | /* | 638 | host->card = card; |
498 | * Check if read-only switch is active. | ||
499 | */ | ||
500 | if (!oldcard) { | ||
501 | if (!host->ops->get_ro || host->ops->get_ro(host) < 0) { | ||
502 | printk(KERN_WARNING "%s: host does not " | ||
503 | "support reading read-only " | ||
504 | "switch. assuming write-enable.\n", | ||
505 | mmc_hostname(host)); | ||
506 | } else { | ||
507 | if (host->ops->get_ro(host) > 0) | ||
508 | mmc_card_set_readonly(card); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | if (!oldcard) | ||
513 | host->card = card; | ||
514 | |||
515 | return 0; | 639 | return 0; |
516 | 640 | ||
517 | free_card: | 641 | free_card: |
518 | if (!oldcard) | 642 | if (!oldcard) |
519 | mmc_remove_card(card); | 643 | mmc_remove_card(card); |
520 | err: | ||
521 | 644 | ||
522 | return err; | 645 | return err; |
523 | } | 646 | } |