aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/sd.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2007-05-01 10:00:02 -0400
committerPierre Ossman <drzeus@drzeus.cx>2007-05-01 10:00:02 -0400
commit6abaa0c9fec563538f2a28a682af8c89bb9b125c (patch)
tree1da7fb5a0b37bd57b38ca52c77ccc72b099fcbae /drivers/mmc/core/sd.c
parent89a73cf52ba2ae4402c53487b71ec4475544f139 (diff)
mmc: support unsafe resume of cards
Since many have the system root on MMC/SD we must allow some foot shooting when it comes to resume. We cannot detect if a card is removed and reinserted during suspend, so the safe approach would be to assume it was, avoiding potential filesystem corruption. This will of course not work if you cannot release the card before suspend. This commit adds a compile time option that makes the MMC layer assume the card wasn't touched if it is redetected upon resume. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/core/sd.c')
-rw-r--r--drivers/mmc/core/sd.c318
1 files changed, 208 insertions, 110 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index ae54e8eb7fea..6597e778f70e 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -263,55 +263,13 @@ out:
263} 263}
264 264
265/* 265/*
266 * Host is being removed. Free up the current card. 266 * Handle the detection and initialisation of a card.
267 */ 267 *
268static void mmc_sd_remove(struct mmc_host *host) 268 * In the case of a resume, "curcard" will contain the card
269{ 269 * we're trying to reinitialise.
270 BUG_ON(!host);
271 BUG_ON(!host->card);
272
273 mmc_remove_card(host->card);
274 host->card = NULL;
275}
276
277/*
278 * Card detection callback from host.
279 */
280static void mmc_sd_detect(struct mmc_host *host)
281{
282 int err;
283
284 BUG_ON(!host);
285 BUG_ON(!host->card);
286
287 mmc_claim_host(host);
288
289 /*
290 * Just check if our card has been removed.
291 */
292 err = mmc_send_status(host->card, NULL);
293
294 mmc_release_host(host);
295
296 if (err != MMC_ERR_NONE) {
297 mmc_remove_card(host->card);
298 host->card = NULL;
299
300 mmc_claim_host(host);
301 mmc_detach_bus(host);
302 mmc_release_host(host);
303 }
304}
305
306static const struct mmc_bus_ops mmc_sd_ops = {
307 .remove = mmc_sd_remove,
308 .detect = mmc_sd_detect,
309};
310
311/*
312 * Starting point for SD card init.
313 */ 270 */
314int mmc_attach_sd(struct mmc_host *host, u32 ocr) 271static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
272 struct mmc_card *oldcard)
315{ 273{
316 struct mmc_card *card; 274 struct mmc_card *card;
317 int err; 275 int err;
@@ -321,34 +279,6 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
321 BUG_ON(!host); 279 BUG_ON(!host);
322 BUG_ON(!host->claimed); 280 BUG_ON(!host->claimed);
323 281
324 mmc_attach_bus(host, &mmc_sd_ops);
325
326 /*
327 * Sanity check the voltages that the card claims to
328 * support.
329 */
330 if (ocr & 0x7F) {
331 printk(KERN_WARNING "%s: card claims to support voltages "
332 "below the defined range. These will be ignored.\n",
333 mmc_hostname(host));
334 ocr &= ~0x7F;
335 }
336
337 if (ocr & MMC_VDD_165_195) {
338 printk(KERN_WARNING "%s: SD card claims to support the "
339 "incompletely defined 'low voltage range'. This "
340 "will be ignored.\n", mmc_hostname(host));
341 ocr &= ~MMC_VDD_165_195;
342 }
343
344 host->ocr = mmc_select_voltage(host, ocr);
345
346 /*
347 * Can we support the voltage(s) of the card(s)?
348 */
349 if (!host->ocr)
350 goto err;
351
352 /* 282 /*
353 * Since we're changing the OCR value, we seem to 283 * Since we're changing the OCR value, we seem to
354 * need to tell some cards to go back to the idle 284 * need to tell some cards to go back to the idle
@@ -363,11 +293,13 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
363 * of the ocr to indicate that we can handle 293 * of the ocr to indicate that we can handle
364 * block-addressed SDHC cards. 294 * block-addressed SDHC cards.
365 */ 295 */
366 err = mmc_send_if_cond(host, host->ocr); 296 err = mmc_send_if_cond(host, ocr);
367 if (err == MMC_ERR_NONE) 297 if (err == MMC_ERR_NONE)
368 ocr = host->ocr | (1 << 30); 298 ocr |= 1 << 30;
369 299
370 mmc_send_app_op_cond(host, ocr, NULL); 300 err = mmc_send_app_op_cond(host, ocr, NULL);
301 if (err != MMC_ERR_NONE)
302 goto err;
371 303
372 /* 304 /*
373 * Fetch CID from card. 305 * Fetch CID from card.
@@ -376,15 +308,22 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
376 if (err != MMC_ERR_NONE) 308 if (err != MMC_ERR_NONE)
377 goto err; 309 goto err;
378 310
379 /* 311 if (oldcard) {
380 * Allocate card structure. 312 if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
381 */ 313 goto err;
382 card = mmc_alloc_card(host);
383 if (IS_ERR(card))
384 goto err;
385 314
386 card->type = MMC_TYPE_SD; 315 card = oldcard;
387 memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); 316 } else {
317 /*
318 * Allocate card structure.
319 */
320 card = mmc_alloc_card(host);
321 if (IS_ERR(card))
322 goto err;
323
324 card->type = MMC_TYPE_SD;
325 memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
326 }
388 327
389 /* 328 /*
390 * Set card RCA. 329 * Set card RCA.
@@ -395,35 +334,42 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
395 334
396 mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); 335 mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
397 336
398 /* 337 if (!oldcard) {
399 * Fetch CSD from card. 338 /*
400 */ 339 * Fetch CSD from card.
401 err = mmc_send_csd(card, card->raw_csd); 340 */
402 if (err != MMC_ERR_NONE) 341 err = mmc_send_csd(card, card->raw_csd);
403 goto free_card; 342 if (err != MMC_ERR_NONE)
343 goto free_card;
404 344
405 mmc_decode_csd(card); 345 mmc_decode_csd(card);
406 mmc_decode_cid(card); 346 mmc_decode_cid(card);
347 }
407 348
408 /* 349 /*
409 * Fetch SCR from card. 350 * Select card, as all following commands rely on that.
410 */ 351 */
411 err = mmc_select_card(card); 352 err = mmc_select_card(card);
412 if (err != MMC_ERR_NONE) 353 if (err != MMC_ERR_NONE)
413 goto free_card; 354 goto free_card;
414 355
415 err = mmc_app_send_scr(card, card->raw_scr); 356 if (!oldcard) {
416 if (err != MMC_ERR_NONE) 357 /*
417 goto free_card; 358 * Fetch SCR from card.
359 */
360 err = mmc_app_send_scr(card, card->raw_scr);
361 if (err != MMC_ERR_NONE)
362 goto free_card;
418 363
419 mmc_decode_scr(card); 364 mmc_decode_scr(card);
420 365
421 /* 366 /*
422 * Fetch switch information from card. 367 * Fetch switch information from card.
423 */ 368 */
424 err = mmc_read_switch(card); 369 err = mmc_read_switch(card);
425 if (err != MMC_ERR_NONE) 370 if (err != MMC_ERR_NONE)
426 goto free_card; 371 goto free_card;
372 }
427 373
428 /* 374 /*
429 * Attempt to change to high-speed (if supported) 375 * Attempt to change to high-speed (if supported)
@@ -458,11 +404,164 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
458 mmc_set_bus_width(host, MMC_BUS_WIDTH_4); 404 mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
459 } 405 }
460 406
461 host->card = card; 407 if (!oldcard)
408 host->card = card;
409
410 return MMC_ERR_NONE;
411
412free_card:
413 if (!oldcard)
414 mmc_remove_card(card);
415err:
416
417 return MMC_ERR_FAILED;
418}
419
420/*
421 * Host is being removed. Free up the current card.
422 */
423static void mmc_sd_remove(struct mmc_host *host)
424{
425 BUG_ON(!host);
426 BUG_ON(!host->card);
427
428 mmc_remove_card(host->card);
429 host->card = NULL;
430}
431
432/*
433 * Card detection callback from host.
434 */
435static void mmc_sd_detect(struct mmc_host *host)
436{
437 int err;
438
439 BUG_ON(!host);
440 BUG_ON(!host->card);
441
442 mmc_claim_host(host);
443
444 /*
445 * Just check if our card has been removed.
446 */
447 err = mmc_send_status(host->card, NULL);
462 448
463 mmc_release_host(host); 449 mmc_release_host(host);
464 450
465 err = mmc_register_card(card); 451 if (err != MMC_ERR_NONE) {
452 mmc_remove_card(host->card);
453 host->card = NULL;
454
455 mmc_claim_host(host);
456 mmc_detach_bus(host);
457 mmc_release_host(host);
458 }
459}
460
461#ifdef CONFIG_MMC_UNSAFE_RESUME
462
463/*
464 * Suspend callback from host.
465 */
466static void mmc_sd_suspend(struct mmc_host *host)
467{
468 BUG_ON(!host);
469 BUG_ON(!host->card);
470
471 mmc_claim_host(host);
472 mmc_deselect_cards(host);
473 host->card->state &= ~MMC_STATE_HIGHSPEED;
474 mmc_release_host(host);
475}
476
477/*
478 * Resume callback from host.
479 *
480 * This function tries to determine if the same card is still present
481 * and, if so, restore all state to it.
482 */
483static void mmc_sd_resume(struct mmc_host *host)
484{
485 int err;
486
487 BUG_ON(!host);
488 BUG_ON(!host->card);
489
490 mmc_claim_host(host);
491
492 err = mmc_sd_init_card(host, host->ocr, host->card);
493 if (err != MMC_ERR_NONE) {
494 mmc_remove_card(host->card);
495 host->card = NULL;
496
497 mmc_detach_bus(host);
498 }
499
500 mmc_release_host(host);
501}
502
503#else
504
505#define mmc_sd_suspend NULL
506#define mmc_sd_resume NULL
507
508#endif
509
510static const struct mmc_bus_ops mmc_sd_ops = {
511 .remove = mmc_sd_remove,
512 .detect = mmc_sd_detect,
513 .suspend = mmc_sd_suspend,
514 .resume = mmc_sd_resume,
515};
516
517/*
518 * Starting point for SD card init.
519 */
520int mmc_attach_sd(struct mmc_host *host, u32 ocr)
521{
522 int err;
523
524 BUG_ON(!host);
525 BUG_ON(!host->claimed);
526
527 mmc_attach_bus(host, &mmc_sd_ops);
528
529 /*
530 * Sanity check the voltages that the card claims to
531 * support.
532 */
533 if (ocr & 0x7F) {
534 printk(KERN_WARNING "%s: card claims to support voltages "
535 "below the defined range. These will be ignored.\n",
536 mmc_hostname(host));
537 ocr &= ~0x7F;
538 }
539
540 if (ocr & MMC_VDD_165_195) {
541 printk(KERN_WARNING "%s: SD card claims to support the "
542 "incompletely defined 'low voltage range'. This "
543 "will be ignored.\n", mmc_hostname(host));
544 ocr &= ~MMC_VDD_165_195;
545 }
546
547 host->ocr = mmc_select_voltage(host, ocr);
548
549 /*
550 * Can we support the voltage(s) of the card(s)?
551 */
552 if (!host->ocr)
553 goto err;
554
555 /*
556 * Detect and init the card.
557 */
558 err = mmc_sd_init_card(host, host->ocr, NULL);
559 if (err != MMC_ERR_NONE)
560 goto err;
561
562 mmc_release_host(host);
563
564 err = mmc_register_card(host->card);
466 if (err) 565 if (err)
467 goto reclaim_host; 566 goto reclaim_host;
468 567
@@ -470,8 +569,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
470 569
471reclaim_host: 570reclaim_host:
472 mmc_claim_host(host); 571 mmc_claim_host(host);
473free_card: 572 mmc_remove_card(host->card);
474 mmc_remove_card(card);
475 host->card = NULL; 573 host->card = NULL;
476err: 574err:
477 mmc_detach_bus(host); 575 mmc_detach_bus(host);