diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 23:41:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 23:41:15 -0500 |
commit | 4b8be38cf782f8ebebc089083fa0572ade79d7ca (patch) | |
tree | 2f88a0a5c1c0be9121c31b5a2775ae2f979cfa66 /drivers/mmc/card | |
parent | 5df1b274cd2f0304339c7f5586fa16cce0fdfce2 (diff) | |
parent | 0db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022 (diff) |
Merge tag 'mmc-merge-for-3.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
MMC highlights for 3.3:
Core:
* Support for the HS200 high-speed eMMC mode.
* Support SDIO 3.0 Ultra High Speed cards.
* Kill pending block requests immediately if card is removed.
* Enable the eMMC feature for locking boot partitions read-only
until next power on, exposed via sysfs.
Drivers:
* Runtime PM support for Intel Medfield SDIO.
* Suspend/resume support for sdhci-spear.
* sh-mmcif now processes requests asynchronously.
* tag 'mmc-merge-for-3.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (58 commits)
mmc: fix a deadlock between system suspend and MMC block IO
mmc: sdhci: restore the enabled dma when do reset all
mmc: dw_mmc: miscaculated the fifo-depth with wrong bit operation
mmc: host: Adds support for eMMC 4.5 HS200 mode
mmc: core: HS200 mode support for eMMC 4.5
mmc: dw_mmc: fixed wrong bit operation for SDMMC_GET_FCNT()
mmc: core: Separate the timeout value for cache-ctrl
mmc: sdhci-spear: Fix compilation error
mmc: sdhci: Deal with failure case in sdhci_suspend_host
mmc: dw_mmc: Clear the DDR mode for non-DDR
mmc: sd: Fix SDR12 timing regression
mmc: sdhci: Fix tuning timer incorrect setting when suspending host
mmc: core: Add option to prevent eMMC sleep command
mmc: omap_hsmmc: use threaded irq handler for card-detect.
mmc: sdhci-pci: enable runtime PM for Medfield SDIO
mmc: sdhci: Always pass clock request value zero to set_clock host op
mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION
mmc: sdhci-pci: get gpio numbers from platform data
mmc: sdhci-pci: add platform data
mmc: sdhci: prevent card detection activity for non-removable cards
...
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r-- | drivers/mmc/card/block.c | 247 | ||||
-rw-r--r-- | drivers/mmc/card/mmc_test.c | 1 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c | 5 |
3 files changed, 198 insertions, 55 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1e0e27cbe987..0cad48a284a8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -107,6 +107,8 @@ struct mmc_blk_data { | |||
107 | */ | 107 | */ |
108 | unsigned int part_curr; | 108 | unsigned int part_curr; |
109 | struct device_attribute force_ro; | 109 | struct device_attribute force_ro; |
110 | struct device_attribute power_ro_lock; | ||
111 | int area_type; | ||
110 | }; | 112 | }; |
111 | 113 | ||
112 | static DEFINE_MUTEX(open_lock); | 114 | static DEFINE_MUTEX(open_lock); |
@@ -119,6 +121,7 @@ enum mmc_blk_status { | |||
119 | MMC_BLK_ABORT, | 121 | MMC_BLK_ABORT, |
120 | MMC_BLK_DATA_ERR, | 122 | MMC_BLK_DATA_ERR, |
121 | MMC_BLK_ECC_ERR, | 123 | MMC_BLK_ECC_ERR, |
124 | MMC_BLK_NOMEDIUM, | ||
122 | }; | 125 | }; |
123 | 126 | ||
124 | module_param(perdev_minors, int, 0444); | 127 | module_param(perdev_minors, int, 0444); |
@@ -165,6 +168,70 @@ static void mmc_blk_put(struct mmc_blk_data *md) | |||
165 | mutex_unlock(&open_lock); | 168 | mutex_unlock(&open_lock); |
166 | } | 169 | } |
167 | 170 | ||
171 | static ssize_t power_ro_lock_show(struct device *dev, | ||
172 | struct device_attribute *attr, char *buf) | ||
173 | { | ||
174 | int ret; | ||
175 | struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); | ||
176 | struct mmc_card *card = md->queue.card; | ||
177 | int locked = 0; | ||
178 | |||
179 | if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PERM_WP_EN) | ||
180 | locked = 2; | ||
181 | else if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_EN) | ||
182 | locked = 1; | ||
183 | |||
184 | ret = snprintf(buf, PAGE_SIZE, "%d\n", locked); | ||
185 | |||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | static ssize_t power_ro_lock_store(struct device *dev, | ||
190 | struct device_attribute *attr, const char *buf, size_t count) | ||
191 | { | ||
192 | int ret; | ||
193 | struct mmc_blk_data *md, *part_md; | ||
194 | struct mmc_card *card; | ||
195 | unsigned long set; | ||
196 | |||
197 | if (kstrtoul(buf, 0, &set)) | ||
198 | return -EINVAL; | ||
199 | |||
200 | if (set != 1) | ||
201 | return count; | ||
202 | |||
203 | md = mmc_blk_get(dev_to_disk(dev)); | ||
204 | card = md->queue.card; | ||
205 | |||
206 | mmc_claim_host(card->host); | ||
207 | |||
208 | ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, | ||
209 | card->ext_csd.boot_ro_lock | | ||
210 | EXT_CSD_BOOT_WP_B_PWR_WP_EN, | ||
211 | card->ext_csd.part_time); | ||
212 | if (ret) | ||
213 | pr_err("%s: Locking boot partition ro until next power on failed: %d\n", md->disk->disk_name, ret); | ||
214 | else | ||
215 | card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN; | ||
216 | |||
217 | mmc_release_host(card->host); | ||
218 | |||
219 | if (!ret) { | ||
220 | pr_info("%s: Locking boot partition ro until next power on\n", | ||
221 | md->disk->disk_name); | ||
222 | set_disk_ro(md->disk, 1); | ||
223 | |||
224 | list_for_each_entry(part_md, &md->part, part) | ||
225 | if (part_md->area_type == MMC_BLK_DATA_AREA_BOOT) { | ||
226 | pr_info("%s: Locking boot partition ro until next power on\n", part_md->disk->disk_name); | ||
227 | set_disk_ro(part_md->disk, 1); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | mmc_blk_put(md); | ||
232 | return count; | ||
233 | } | ||
234 | |||
168 | static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, | 235 | static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, |
169 | char *buf) | 236 | char *buf) |
170 | { | 237 | { |
@@ -266,6 +333,9 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( | |||
266 | goto idata_err; | 333 | goto idata_err; |
267 | } | 334 | } |
268 | 335 | ||
336 | if (!idata->buf_bytes) | ||
337 | return idata; | ||
338 | |||
269 | idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); | 339 | idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); |
270 | if (!idata->buf) { | 340 | if (!idata->buf) { |
271 | err = -ENOMEM; | 341 | err = -ENOMEM; |
@@ -312,25 +382,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
312 | if (IS_ERR(idata)) | 382 | if (IS_ERR(idata)) |
313 | return PTR_ERR(idata); | 383 | return PTR_ERR(idata); |
314 | 384 | ||
315 | cmd.opcode = idata->ic.opcode; | ||
316 | cmd.arg = idata->ic.arg; | ||
317 | cmd.flags = idata->ic.flags; | ||
318 | |||
319 | data.sg = &sg; | ||
320 | data.sg_len = 1; | ||
321 | data.blksz = idata->ic.blksz; | ||
322 | data.blocks = idata->ic.blocks; | ||
323 | |||
324 | sg_init_one(data.sg, idata->buf, idata->buf_bytes); | ||
325 | |||
326 | if (idata->ic.write_flag) | ||
327 | data.flags = MMC_DATA_WRITE; | ||
328 | else | ||
329 | data.flags = MMC_DATA_READ; | ||
330 | |||
331 | mrq.cmd = &cmd; | ||
332 | mrq.data = &data; | ||
333 | |||
334 | md = mmc_blk_get(bdev->bd_disk); | 385 | md = mmc_blk_get(bdev->bd_disk); |
335 | if (!md) { | 386 | if (!md) { |
336 | err = -EINVAL; | 387 | err = -EINVAL; |
@@ -343,6 +394,48 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
343 | goto cmd_done; | 394 | goto cmd_done; |
344 | } | 395 | } |
345 | 396 | ||
397 | cmd.opcode = idata->ic.opcode; | ||
398 | cmd.arg = idata->ic.arg; | ||
399 | cmd.flags = idata->ic.flags; | ||
400 | |||
401 | if (idata->buf_bytes) { | ||
402 | data.sg = &sg; | ||
403 | data.sg_len = 1; | ||
404 | data.blksz = idata->ic.blksz; | ||
405 | data.blocks = idata->ic.blocks; | ||
406 | |||
407 | sg_init_one(data.sg, idata->buf, idata->buf_bytes); | ||
408 | |||
409 | if (idata->ic.write_flag) | ||
410 | data.flags = MMC_DATA_WRITE; | ||
411 | else | ||
412 | data.flags = MMC_DATA_READ; | ||
413 | |||
414 | /* data.flags must already be set before doing this. */ | ||
415 | mmc_set_data_timeout(&data, card); | ||
416 | |||
417 | /* Allow overriding the timeout_ns for empirical tuning. */ | ||
418 | if (idata->ic.data_timeout_ns) | ||
419 | data.timeout_ns = idata->ic.data_timeout_ns; | ||
420 | |||
421 | if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { | ||
422 | /* | ||
423 | * Pretend this is a data transfer and rely on the | ||
424 | * host driver to compute timeout. When all host | ||
425 | * drivers support cmd.cmd_timeout for R1B, this | ||
426 | * can be changed to: | ||
427 | * | ||
428 | * mrq.data = NULL; | ||
429 | * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; | ||
430 | */ | ||
431 | data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; | ||
432 | } | ||
433 | |||
434 | mrq.data = &data; | ||
435 | } | ||
436 | |||
437 | mrq.cmd = &cmd; | ||
438 | |||
346 | mmc_claim_host(card->host); | 439 | mmc_claim_host(card->host); |
347 | 440 | ||
348 | if (idata->ic.is_acmd) { | 441 | if (idata->ic.is_acmd) { |
@@ -351,24 +444,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
351 | goto cmd_rel_host; | 444 | goto cmd_rel_host; |
352 | } | 445 | } |
353 | 446 | ||
354 | /* data.flags must already be set before doing this. */ | ||
355 | mmc_set_data_timeout(&data, card); | ||
356 | /* Allow overriding the timeout_ns for empirical tuning. */ | ||
357 | if (idata->ic.data_timeout_ns) | ||
358 | data.timeout_ns = idata->ic.data_timeout_ns; | ||
359 | |||
360 | if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { | ||
361 | /* | ||
362 | * Pretend this is a data transfer and rely on the host driver | ||
363 | * to compute timeout. When all host drivers support | ||
364 | * cmd.cmd_timeout for R1B, this can be changed to: | ||
365 | * | ||
366 | * mrq.data = NULL; | ||
367 | * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; | ||
368 | */ | ||
369 | data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; | ||
370 | } | ||
371 | |||
372 | mmc_wait_for_req(card->host, &mrq); | 447 | mmc_wait_for_req(card->host, &mrq); |
373 | 448 | ||
374 | if (cmd.error) { | 449 | if (cmd.error) { |
@@ -565,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries) | |||
565 | return err; | 640 | return err; |
566 | } | 641 | } |
567 | 642 | ||
643 | #define ERR_NOMEDIUM 3 | ||
568 | #define ERR_RETRY 2 | 644 | #define ERR_RETRY 2 |
569 | #define ERR_ABORT 1 | 645 | #define ERR_ABORT 1 |
570 | #define ERR_CONTINUE 0 | 646 | #define ERR_CONTINUE 0 |
@@ -632,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, | |||
632 | u32 status, stop_status = 0; | 708 | u32 status, stop_status = 0; |
633 | int err, retry; | 709 | int err, retry; |
634 | 710 | ||
711 | if (mmc_card_removed(card)) | ||
712 | return ERR_NOMEDIUM; | ||
713 | |||
635 | /* | 714 | /* |
636 | * Try to get card status which indicates both the card state | 715 | * Try to get card status which indicates both the card state |
637 | * and why there was no response. If the first attempt fails, | 716 | * and why there was no response. If the first attempt fails, |
@@ -648,8 +727,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, | |||
648 | } | 727 | } |
649 | 728 | ||
650 | /* We couldn't get a response from the card. Give up. */ | 729 | /* We couldn't get a response from the card. Give up. */ |
651 | if (err) | 730 | if (err) { |
731 | /* Check if the card is removed */ | ||
732 | if (mmc_detect_card_removed(card->host)) | ||
733 | return ERR_NOMEDIUM; | ||
652 | return ERR_ABORT; | 734 | return ERR_ABORT; |
735 | } | ||
653 | 736 | ||
654 | /* Flag ECC errors */ | 737 | /* Flag ECC errors */ |
655 | if ((status & R1_CARD_ECC_FAILED) || | 738 | if ((status & R1_CARD_ECC_FAILED) || |
@@ -922,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card, | |||
922 | return MMC_BLK_RETRY; | 1005 | return MMC_BLK_RETRY; |
923 | case ERR_ABORT: | 1006 | case ERR_ABORT: |
924 | return MMC_BLK_ABORT; | 1007 | return MMC_BLK_ABORT; |
1008 | case ERR_NOMEDIUM: | ||
1009 | return MMC_BLK_NOMEDIUM; | ||
925 | case ERR_CONTINUE: | 1010 | case ERR_CONTINUE: |
926 | break; | 1011 | break; |
927 | } | 1012 | } |
@@ -1255,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1255 | if (!ret) | 1340 | if (!ret) |
1256 | goto start_new_req; | 1341 | goto start_new_req; |
1257 | break; | 1342 | break; |
1343 | case MMC_BLK_NOMEDIUM: | ||
1344 | goto cmd_abort; | ||
1258 | } | 1345 | } |
1259 | 1346 | ||
1260 | if (ret) { | 1347 | if (ret) { |
@@ -1271,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1271 | 1358 | ||
1272 | cmd_abort: | 1359 | cmd_abort: |
1273 | spin_lock_irq(&md->lock); | 1360 | spin_lock_irq(&md->lock); |
1361 | if (mmc_card_removed(card)) | ||
1362 | req->cmd_flags |= REQ_QUIET; | ||
1274 | while (ret) | 1363 | while (ret) |
1275 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); | 1364 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); |
1276 | spin_unlock_irq(&md->lock); | 1365 | spin_unlock_irq(&md->lock); |
@@ -1339,7 +1428,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
1339 | struct device *parent, | 1428 | struct device *parent, |
1340 | sector_t size, | 1429 | sector_t size, |
1341 | bool default_ro, | 1430 | bool default_ro, |
1342 | const char *subname) | 1431 | const char *subname, |
1432 | int area_type) | ||
1343 | { | 1433 | { |
1344 | struct mmc_blk_data *md; | 1434 | struct mmc_blk_data *md; |
1345 | int devidx, ret; | 1435 | int devidx, ret; |
@@ -1364,11 +1454,12 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
1364 | if (!subname) { | 1454 | if (!subname) { |
1365 | md->name_idx = find_first_zero_bit(name_use, max_devices); | 1455 | md->name_idx = find_first_zero_bit(name_use, max_devices); |
1366 | __set_bit(md->name_idx, name_use); | 1456 | __set_bit(md->name_idx, name_use); |
1367 | } | 1457 | } else |
1368 | else | ||
1369 | md->name_idx = ((struct mmc_blk_data *) | 1458 | md->name_idx = ((struct mmc_blk_data *) |
1370 | dev_to_disk(parent)->private_data)->name_idx; | 1459 | dev_to_disk(parent)->private_data)->name_idx; |
1371 | 1460 | ||
1461 | md->area_type = area_type; | ||
1462 | |||
1372 | /* | 1463 | /* |
1373 | * Set the read-only status based on the supported commands | 1464 | * Set the read-only status based on the supported commands |
1374 | * and the write protect switch. | 1465 | * and the write protect switch. |
@@ -1462,7 +1553,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
1462 | size = card->csd.capacity << (card->csd.read_blkbits - 9); | 1553 | size = card->csd.capacity << (card->csd.read_blkbits - 9); |
1463 | } | 1554 | } |
1464 | 1555 | ||
1465 | md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL); | 1556 | md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL, |
1557 | MMC_BLK_DATA_AREA_MAIN); | ||
1466 | return md; | 1558 | return md; |
1467 | } | 1559 | } |
1468 | 1560 | ||
@@ -1471,13 +1563,14 @@ static int mmc_blk_alloc_part(struct mmc_card *card, | |||
1471 | unsigned int part_type, | 1563 | unsigned int part_type, |
1472 | sector_t size, | 1564 | sector_t size, |
1473 | bool default_ro, | 1565 | bool default_ro, |
1474 | const char *subname) | 1566 | const char *subname, |
1567 | int area_type) | ||
1475 | { | 1568 | { |
1476 | char cap_str[10]; | 1569 | char cap_str[10]; |
1477 | struct mmc_blk_data *part_md; | 1570 | struct mmc_blk_data *part_md; |
1478 | 1571 | ||
1479 | part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, | 1572 | part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, |
1480 | subname); | 1573 | subname, area_type); |
1481 | if (IS_ERR(part_md)) | 1574 | if (IS_ERR(part_md)) |
1482 | return PTR_ERR(part_md); | 1575 | return PTR_ERR(part_md); |
1483 | part_md->part_type = part_type; | 1576 | part_md->part_type = part_type; |
@@ -1510,7 +1603,8 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) | |||
1510 | card->part[idx].part_cfg, | 1603 | card->part[idx].part_cfg, |
1511 | card->part[idx].size >> 9, | 1604 | card->part[idx].size >> 9, |
1512 | card->part[idx].force_ro, | 1605 | card->part[idx].force_ro, |
1513 | card->part[idx].name); | 1606 | card->part[idx].name, |
1607 | card->part[idx].area_type); | ||
1514 | if (ret) | 1608 | if (ret) |
1515 | return ret; | 1609 | return ret; |
1516 | } | 1610 | } |
@@ -1539,9 +1633,16 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
1539 | 1633 | ||
1540 | static void mmc_blk_remove_req(struct mmc_blk_data *md) | 1634 | static void mmc_blk_remove_req(struct mmc_blk_data *md) |
1541 | { | 1635 | { |
1636 | struct mmc_card *card; | ||
1637 | |||
1542 | if (md) { | 1638 | if (md) { |
1639 | card = md->queue.card; | ||
1543 | if (md->disk->flags & GENHD_FL_UP) { | 1640 | if (md->disk->flags & GENHD_FL_UP) { |
1544 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); | 1641 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); |
1642 | if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && | ||
1643 | card->ext_csd.boot_ro_lockable) | ||
1644 | device_remove_file(disk_to_dev(md->disk), | ||
1645 | &md->power_ro_lock); | ||
1545 | 1646 | ||
1546 | /* Stop new requests from getting into the queue */ | 1647 | /* Stop new requests from getting into the queue */ |
1547 | del_gendisk(md->disk); | 1648 | del_gendisk(md->disk); |
@@ -1570,6 +1671,7 @@ static void mmc_blk_remove_parts(struct mmc_card *card, | |||
1570 | static int mmc_add_disk(struct mmc_blk_data *md) | 1671 | static int mmc_add_disk(struct mmc_blk_data *md) |
1571 | { | 1672 | { |
1572 | int ret; | 1673 | int ret; |
1674 | struct mmc_card *card = md->queue.card; | ||
1573 | 1675 | ||
1574 | add_disk(md->disk); | 1676 | add_disk(md->disk); |
1575 | md->force_ro.show = force_ro_show; | 1677 | md->force_ro.show = force_ro_show; |
@@ -1579,18 +1681,53 @@ static int mmc_add_disk(struct mmc_blk_data *md) | |||
1579 | md->force_ro.attr.mode = S_IRUGO | S_IWUSR; | 1681 | md->force_ro.attr.mode = S_IRUGO | S_IWUSR; |
1580 | ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); | 1682 | ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); |
1581 | if (ret) | 1683 | if (ret) |
1582 | del_gendisk(md->disk); | 1684 | goto force_ro_fail; |
1685 | |||
1686 | if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && | ||
1687 | card->ext_csd.boot_ro_lockable) { | ||
1688 | mode_t mode; | ||
1689 | |||
1690 | if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_DIS) | ||
1691 | mode = S_IRUGO; | ||
1692 | else | ||
1693 | mode = S_IRUGO | S_IWUSR; | ||
1694 | |||
1695 | md->power_ro_lock.show = power_ro_lock_show; | ||
1696 | md->power_ro_lock.store = power_ro_lock_store; | ||
1697 | md->power_ro_lock.attr.mode = mode; | ||
1698 | md->power_ro_lock.attr.name = | ||
1699 | "ro_lock_until_next_power_on"; | ||
1700 | ret = device_create_file(disk_to_dev(md->disk), | ||
1701 | &md->power_ro_lock); | ||
1702 | if (ret) | ||
1703 | goto power_ro_lock_fail; | ||
1704 | } | ||
1705 | return ret; | ||
1706 | |||
1707 | power_ro_lock_fail: | ||
1708 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); | ||
1709 | force_ro_fail: | ||
1710 | del_gendisk(md->disk); | ||
1583 | 1711 | ||
1584 | return ret; | 1712 | return ret; |
1585 | } | 1713 | } |
1586 | 1714 | ||
1715 | #define CID_MANFID_SANDISK 0x2 | ||
1716 | #define CID_MANFID_TOSHIBA 0x11 | ||
1717 | #define CID_MANFID_MICRON 0x13 | ||
1718 | |||
1587 | static const struct mmc_fixup blk_fixups[] = | 1719 | static const struct mmc_fixup blk_fixups[] = |
1588 | { | 1720 | { |
1589 | MMC_FIXUP("SEM02G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1721 | MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk, |
1590 | MMC_FIXUP("SEM04G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1722 | MMC_QUIRK_INAND_CMD38), |
1591 | MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1723 | MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk, |
1592 | MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1724 | MMC_QUIRK_INAND_CMD38), |
1593 | MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1725 | MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk, |
1726 | MMC_QUIRK_INAND_CMD38), | ||
1727 | MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
1728 | MMC_QUIRK_INAND_CMD38), | ||
1729 | MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
1730 | MMC_QUIRK_INAND_CMD38), | ||
1594 | 1731 | ||
1595 | /* | 1732 | /* |
1596 | * Some MMC cards experience performance degradation with CMD23 | 1733 | * Some MMC cards experience performance degradation with CMD23 |
@@ -1600,18 +1737,18 @@ static const struct mmc_fixup blk_fixups[] = | |||
1600 | * | 1737 | * |
1601 | * N.B. This doesn't affect SD cards. | 1738 | * N.B. This doesn't affect SD cards. |
1602 | */ | 1739 | */ |
1603 | MMC_FIXUP("MMC08G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1740 | MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
1604 | MMC_QUIRK_BLK_NO_CMD23), | 1741 | MMC_QUIRK_BLK_NO_CMD23), |
1605 | MMC_FIXUP("MMC16G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1742 | MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
1606 | MMC_QUIRK_BLK_NO_CMD23), | 1743 | MMC_QUIRK_BLK_NO_CMD23), |
1607 | MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1744 | MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
1608 | MMC_QUIRK_BLK_NO_CMD23), | 1745 | MMC_QUIRK_BLK_NO_CMD23), |
1609 | 1746 | ||
1610 | /* | 1747 | /* |
1611 | * Some Micron MMC cards needs longer data read timeout than | 1748 | * Some Micron MMC cards needs longer data read timeout than |
1612 | * indicated in CSD. | 1749 | * indicated in CSD. |
1613 | */ | 1750 | */ |
1614 | MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc, | 1751 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, |
1615 | MMC_QUIRK_LONG_READ_TIME), | 1752 | MMC_QUIRK_LONG_READ_TIME), |
1616 | 1753 | ||
1617 | END_FIXUP | 1754 | END_FIXUP |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index e99bdc18002d..759714ed6bee 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -1581,6 +1581,7 @@ static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill) | |||
1581 | 1581 | ||
1582 | t->max_segs = test->card->host->max_segs; | 1582 | t->max_segs = test->card->host->max_segs; |
1583 | t->max_seg_sz = test->card->host->max_seg_size; | 1583 | t->max_seg_sz = test->card->host->max_seg_size; |
1584 | t->max_seg_sz -= t->max_seg_sz % 512; | ||
1584 | 1585 | ||
1585 | t->max_tfr = t->max_sz; | 1586 | t->max_tfr = t->max_sz; |
1586 | if (t->max_tfr >> 9 > test->card->host->max_blk_count) | 1587 | if (t->max_tfr >> 9 > test->card->host->max_blk_count) |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index dcad59cbfef1..2517547b4366 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -29,6 +29,8 @@ | |||
29 | */ | 29 | */ |
30 | static int mmc_prep_request(struct request_queue *q, struct request *req) | 30 | static int mmc_prep_request(struct request_queue *q, struct request *req) |
31 | { | 31 | { |
32 | struct mmc_queue *mq = q->queuedata; | ||
33 | |||
32 | /* | 34 | /* |
33 | * We only like normal block requests and discards. | 35 | * We only like normal block requests and discards. |
34 | */ | 36 | */ |
@@ -37,6 +39,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) | |||
37 | return BLKPREP_KILL; | 39 | return BLKPREP_KILL; |
38 | } | 40 | } |
39 | 41 | ||
42 | if (mq && mmc_card_removed(mq->card)) | ||
43 | return BLKPREP_KILL; | ||
44 | |||
40 | req->cmd_flags |= REQ_DONTPREP; | 45 | req->cmd_flags |= REQ_DONTPREP; |
41 | 46 | ||
42 | return BLKPREP_OK; | 47 | return BLKPREP_OK; |