aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2011-06-28 10:16:02 -0400
committerChris Ball <cjb@laptop.org>2011-07-20 17:21:03 -0400
commite056a1b5b67b4e4bfad00bf143ab14f634777705 (patch)
treec9cd3a6144787bcb434e52a4a32dec3c37e9f343 /drivers/mmc
parente8cd77e467f7bb1d4b942037c47b087334a484d4 (diff)
mmc: queue: let host controllers specify maximum discard timeout
Some host controllers will not operate without a hardware timeout that is limited in value. However large discards require large timeouts, so there needs to be a way to specify the maximum discard size. A host controller driver may now specify the maximum discard timeout possible so that max_discard_sectors can be calculated. However, for eMMC when the High Capacity Erase Group Size is not in use, the timeout calculation depends on clock rate which may change. For that case Preferred Erase Size is used instead. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/card/queue.c33
-rw-r--r--drivers/mmc/core/core.c76
2 files changed, 99 insertions, 10 deletions
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 6413afa318d2..defc11b4572c 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -101,6 +101,27 @@ static void mmc_request(struct request_queue *q)
101 wake_up_process(mq->thread); 101 wake_up_process(mq->thread);
102} 102}
103 103
104static void mmc_queue_setup_discard(struct request_queue *q,
105 struct mmc_card *card)
106{
107 unsigned max_discard;
108
109 max_discard = mmc_calc_max_discard(card);
110 if (!max_discard)
111 return;
112
113 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
114 q->limits.max_discard_sectors = max_discard;
115 if (card->erased_byte == 0)
116 q->limits.discard_zeroes_data = 1;
117 q->limits.discard_granularity = card->pref_erase << 9;
118 /* granularity must not be greater than max. discard */
119 if (card->pref_erase > max_discard)
120 q->limits.discard_granularity = 0;
121 if (mmc_can_secure_erase_trim(card))
122 queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
123}
124
104/** 125/**
105 * mmc_init_queue - initialise a queue structure. 126 * mmc_init_queue - initialise a queue structure.
106 * @mq: mmc queue 127 * @mq: mmc queue
@@ -130,16 +151,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
130 151
131 blk_queue_prep_rq(mq->queue, mmc_prep_request); 152 blk_queue_prep_rq(mq->queue, mmc_prep_request);
132 queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue); 153 queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
133 if (mmc_can_erase(card)) { 154 if (mmc_can_erase(card))
134 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mq->queue); 155 mmc_queue_setup_discard(mq->queue, card);
135 mq->queue->limits.max_discard_sectors = UINT_MAX;
136 if (card->erased_byte == 0)
137 mq->queue->limits.discard_zeroes_data = 1;
138 mq->queue->limits.discard_granularity = card->pref_erase << 9;
139 if (mmc_can_secure_erase_trim(card))
140 queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD,
141 mq->queue);
142 }
143 156
144#ifdef CONFIG_MMC_BLOCK_BOUNCE 157#ifdef CONFIG_MMC_BLOCK_BOUNCE
145 if (host->max_segs == 1) { 158 if (host->max_segs == 1) {
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7843efe22359..ac82865b8c2f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1516,6 +1516,82 @@ int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,
1516} 1516}
1517EXPORT_SYMBOL(mmc_erase_group_aligned); 1517EXPORT_SYMBOL(mmc_erase_group_aligned);
1518 1518
1519static unsigned int mmc_do_calc_max_discard(struct mmc_card *card,
1520 unsigned int arg)
1521{
1522 struct mmc_host *host = card->host;
1523 unsigned int max_discard, x, y, qty = 0, max_qty, timeout;
1524 unsigned int last_timeout = 0;
1525
1526 if (card->erase_shift)
1527 max_qty = UINT_MAX >> card->erase_shift;
1528 else if (mmc_card_sd(card))
1529 max_qty = UINT_MAX;
1530 else
1531 max_qty = UINT_MAX / card->erase_size;
1532
1533 /* Find the largest qty with an OK timeout */
1534 do {
1535 y = 0;
1536 for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) {
1537 timeout = mmc_erase_timeout(card, arg, qty + x);
1538 if (timeout > host->max_discard_to)
1539 break;
1540 if (timeout < last_timeout)
1541 break;
1542 last_timeout = timeout;
1543 y = x;
1544 }
1545 qty += y;
1546 } while (y);
1547
1548 if (!qty)
1549 return 0;
1550
1551 if (qty == 1)
1552 return 1;
1553
1554 /* Convert qty to sectors */
1555 if (card->erase_shift)
1556 max_discard = --qty << card->erase_shift;
1557 else if (mmc_card_sd(card))
1558 max_discard = qty;
1559 else
1560 max_discard = --qty * card->erase_size;
1561
1562 return max_discard;
1563}
1564
1565unsigned int mmc_calc_max_discard(struct mmc_card *card)
1566{
1567 struct mmc_host *host = card->host;
1568 unsigned int max_discard, max_trim;
1569
1570 if (!host->max_discard_to)
1571 return UINT_MAX;
1572
1573 /*
1574 * Without erase_group_def set, MMC erase timeout depends on clock
1575 * frequence which can change. In that case, the best choice is
1576 * just the preferred erase size.
1577 */
1578 if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1))
1579 return card->pref_erase;
1580
1581 max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG);
1582 if (mmc_can_trim(card)) {
1583 max_trim = mmc_do_calc_max_discard(card, MMC_TRIM_ARG);
1584 if (max_trim < max_discard)
1585 max_discard = max_trim;
1586 } else if (max_discard < card->erase_size) {
1587 max_discard = 0;
1588 }
1589 pr_debug("%s: calculated max. discard sectors %u for timeout %u ms\n",
1590 mmc_hostname(host), max_discard, host->max_discard_to);
1591 return max_discard;
1592}
1593EXPORT_SYMBOL(mmc_calc_max_discard);
1594
1519int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen) 1595int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)
1520{ 1596{
1521 struct mmc_command cmd = {0}; 1597 struct mmc_command cmd = {0};