diff options
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r-- | drivers/mmc/card/block.c | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 00073b7c0368..217f82037fc1 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -43,15 +43,27 @@ | |||
43 | #include "queue.h" | 43 | #include "queue.h" |
44 | 44 | ||
45 | MODULE_ALIAS("mmc:block"); | 45 | MODULE_ALIAS("mmc:block"); |
46 | #ifdef MODULE_PARAM_PREFIX | ||
47 | #undef MODULE_PARAM_PREFIX | ||
48 | #endif | ||
49 | #define MODULE_PARAM_PREFIX "mmcblk." | ||
50 | |||
51 | static DEFINE_MUTEX(block_mutex); | ||
46 | 52 | ||
47 | /* | 53 | /* |
48 | * max 8 partitions per card | 54 | * The defaults come from config options but can be overriden by module |
55 | * or bootarg options. | ||
49 | */ | 56 | */ |
50 | #define MMC_SHIFT 3 | 57 | static int perdev_minors = CONFIG_MMC_BLOCK_MINORS; |
51 | #define MMC_NUM_MINORS (256 >> MMC_SHIFT) | ||
52 | 58 | ||
53 | static DEFINE_MUTEX(block_mutex); | 59 | /* |
54 | static DECLARE_BITMAP(dev_use, MMC_NUM_MINORS); | 60 | * We've only got one major, so number of mmcblk devices is |
61 | * limited to 256 / number of minors per device. | ||
62 | */ | ||
63 | static int max_devices; | ||
64 | |||
65 | /* 256 minors, so at most 256 separate devices */ | ||
66 | static DECLARE_BITMAP(dev_use, 256); | ||
55 | 67 | ||
56 | /* | 68 | /* |
57 | * There is one mmc_blk_data per slot. | 69 | * There is one mmc_blk_data per slot. |
@@ -67,6 +79,9 @@ struct mmc_blk_data { | |||
67 | 79 | ||
68 | static DEFINE_MUTEX(open_lock); | 80 | static DEFINE_MUTEX(open_lock); |
69 | 81 | ||
82 | module_param(perdev_minors, int, 0444); | ||
83 | MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); | ||
84 | |||
70 | static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) | 85 | static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) |
71 | { | 86 | { |
72 | struct mmc_blk_data *md; | 87 | struct mmc_blk_data *md; |
@@ -88,10 +103,10 @@ static void mmc_blk_put(struct mmc_blk_data *md) | |||
88 | md->usage--; | 103 | md->usage--; |
89 | if (md->usage == 0) { | 104 | if (md->usage == 0) { |
90 | int devmaj = MAJOR(disk_devt(md->disk)); | 105 | int devmaj = MAJOR(disk_devt(md->disk)); |
91 | int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; | 106 | int devidx = MINOR(disk_devt(md->disk)) / perdev_minors; |
92 | 107 | ||
93 | if (!devmaj) | 108 | if (!devmaj) |
94 | devidx = md->disk->first_minor >> MMC_SHIFT; | 109 | devidx = md->disk->first_minor / perdev_minors; |
95 | 110 | ||
96 | blk_cleanup_queue(md->queue.queue); | 111 | blk_cleanup_queue(md->queue.queue); |
97 | 112 | ||
@@ -373,7 +388,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) | |||
373 | readcmd = MMC_READ_SINGLE_BLOCK; | 388 | readcmd = MMC_READ_SINGLE_BLOCK; |
374 | writecmd = MMC_WRITE_BLOCK; | 389 | writecmd = MMC_WRITE_BLOCK; |
375 | } | 390 | } |
376 | |||
377 | if (rq_data_dir(req) == READ) { | 391 | if (rq_data_dir(req) == READ) { |
378 | brq.cmd.opcode = readcmd; | 392 | brq.cmd.opcode = readcmd; |
379 | brq.data.flags |= MMC_DATA_READ; | 393 | brq.data.flags |= MMC_DATA_READ; |
@@ -567,8 +581,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
567 | struct mmc_blk_data *md; | 581 | struct mmc_blk_data *md; |
568 | int devidx, ret; | 582 | int devidx, ret; |
569 | 583 | ||
570 | devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS); | 584 | devidx = find_first_zero_bit(dev_use, max_devices); |
571 | if (devidx >= MMC_NUM_MINORS) | 585 | if (devidx >= max_devices) |
572 | return ERR_PTR(-ENOSPC); | 586 | return ERR_PTR(-ENOSPC); |
573 | __set_bit(devidx, dev_use); | 587 | __set_bit(devidx, dev_use); |
574 | 588 | ||
@@ -585,7 +599,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
585 | */ | 599 | */ |
586 | md->read_only = mmc_blk_readonly(card); | 600 | md->read_only = mmc_blk_readonly(card); |
587 | 601 | ||
588 | md->disk = alloc_disk(1 << MMC_SHIFT); | 602 | md->disk = alloc_disk(perdev_minors); |
589 | if (md->disk == NULL) { | 603 | if (md->disk == NULL) { |
590 | ret = -ENOMEM; | 604 | ret = -ENOMEM; |
591 | goto err_kfree; | 605 | goto err_kfree; |
@@ -602,7 +616,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
602 | md->queue.data = md; | 616 | md->queue.data = md; |
603 | 617 | ||
604 | md->disk->major = MMC_BLOCK_MAJOR; | 618 | md->disk->major = MMC_BLOCK_MAJOR; |
605 | md->disk->first_minor = devidx << MMC_SHIFT; | 619 | md->disk->first_minor = devidx * perdev_minors; |
606 | md->disk->fops = &mmc_bdops; | 620 | md->disk->fops = &mmc_bdops; |
607 | md->disk->private_data = md; | 621 | md->disk->private_data = md; |
608 | md->disk->queue = md->queue.queue; | 622 | md->disk->queue = md->queue.queue; |
@@ -620,7 +634,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
620 | * messages to tell when the card is present. | 634 | * messages to tell when the card is present. |
621 | */ | 635 | */ |
622 | 636 | ||
623 | sprintf(md->disk->disk_name, "mmcblk%d", devidx); | 637 | snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), |
638 | "mmcblk%d", devidx); | ||
624 | 639 | ||
625 | blk_queue_logical_block_size(md->queue.queue, 512); | 640 | blk_queue_logical_block_size(md->queue.queue, 512); |
626 | 641 | ||
@@ -651,23 +666,15 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
651 | static int | 666 | static int |
652 | mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | 667 | mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) |
653 | { | 668 | { |
654 | struct mmc_command cmd; | ||
655 | int err; | 669 | int err; |
656 | 670 | ||
657 | /* Block-addressed cards ignore MMC_SET_BLOCKLEN. */ | ||
658 | if (mmc_card_blockaddr(card)) | ||
659 | return 0; | ||
660 | |||
661 | mmc_claim_host(card->host); | 671 | mmc_claim_host(card->host); |
662 | cmd.opcode = MMC_SET_BLOCKLEN; | 672 | err = mmc_set_blocklen(card, 512); |
663 | cmd.arg = 512; | ||
664 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; | ||
665 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | ||
666 | mmc_release_host(card->host); | 673 | mmc_release_host(card->host); |
667 | 674 | ||
668 | if (err) { | 675 | if (err) { |
669 | printk(KERN_ERR "%s: unable to set block size to %d: %d\n", | 676 | printk(KERN_ERR "%s: unable to set block size to 512: %d\n", |
670 | md->disk->disk_name, cmd.arg, err); | 677 | md->disk->disk_name, err); |
671 | return -EINVAL; | 678 | return -EINVAL; |
672 | } | 679 | } |
673 | 680 | ||
@@ -678,7 +685,6 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
678 | { | 685 | { |
679 | struct mmc_blk_data *md; | 686 | struct mmc_blk_data *md; |
680 | int err; | 687 | int err; |
681 | |||
682 | char cap_str[10]; | 688 | char cap_str[10]; |
683 | 689 | ||
684 | /* | 690 | /* |
@@ -768,6 +774,11 @@ static int __init mmc_blk_init(void) | |||
768 | { | 774 | { |
769 | int res; | 775 | int res; |
770 | 776 | ||
777 | if (perdev_minors != CONFIG_MMC_BLOCK_MINORS) | ||
778 | pr_info("mmcblk: using %d minors per device\n", perdev_minors); | ||
779 | |||
780 | max_devices = 256 / perdev_minors; | ||
781 | |||
771 | res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); | 782 | res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); |
772 | if (res) | 783 | if (res) |
773 | goto out; | 784 | goto out; |