On 25 November 2016 at 10:35, Linus Walleij <linus.walleij@xxxxxxxxxx> wrote: > I've had it with this code now. > > The packed command support is a complex hurdle in the MMC/SD block > layer, around 500+ lines of code which was introduced in 2013 in > commits > > ce39f9d17c14 ("mmc: support packed write command for eMMC4.5 devices") > abd9ac144947 ("mmc: add packed command feature of eMMC4.5") > > ...and since then it has been rotting. The original author of the > code has disappeared from the community and the mail address is > bouncing. > > For the code to be exercised the host must flag that it supports > packed commands, so in mmc_blk_prep_packed_list() which is called for > every single request, the following construction appears: > > u8 max_packed_rw = 0; > > if ((rq_data_dir(cur) == WRITE) && > mmc_host_packed_wr(card->host)) > max_packed_rw = card->ext_csd.max_packed_writes; > > if (max_packed_rw == 0) > goto no_packed; > > This has the following logical deductions: > > - Only WRITE commands can really be packed, so the solution is > only half-done: we support packed WRITE but not packed READ. > The packed command support has not been finalized by supporting > reads in three years! > > - mmc_host_packed_wr() is just a static inline that checks > host->caps2 & MMC_CAP2_PACKED_WR. The problem with this is > that NO upstream host sets this capability flag! No driver > in the kernel is using it, and we can't test it. Packed > command may be supported in out-of-tree code, but I doubt > it. I doubt that the code is even working anymore due to > other refactorings in the MMC block layer, who would > notice if patches affecting it broke packed commands? > No one. > > - There is no Device Tree binding or code to mark a host as > supporting packed read or write commands, just this flag > in caps2, so for sure there are not any DT systems using > it either. > > It has other problems as well: mmc_blk_prep_packed_list() is > speculatively picking requests out of the request queue with > blk_fetch_request() making the MMC/SD stack harder to convert > to the multiqueue block layer. By this we get rid of an > obstacle. > > The way I see it this is just cruft littering the MMC/SD > stack. > > Cc: Namjae Jeon <namjae.jeon@xxxxxxxxxxx> > Cc: Maya Erez <qca_merez@xxxxxxxxxxxxxxxx> > Acked-by: Jaehoon Chung <jh80.chung@xxxxxxxxxxx> > Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> Thanks, applied for next! Kind regards Uffe > --- > ChangeLog v2->v3: > - Remove unused "reqs" variable, found by the build robot. > ChangeLog v1->v2: > - Rebased on Ulf's next branch > - Added Jaehoon's ACK > --- > drivers/mmc/card/block.c | 483 ++--------------------------------------------- > drivers/mmc/card/queue.c | 53 +----- > drivers/mmc/card/queue.h | 19 -- > include/linux/mmc/host.h | 5 - > 4 files changed, 20 insertions(+), 540 deletions(-) > > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c > index 6618126fcb9f..86ff28f84698 100644 > --- a/drivers/mmc/card/block.c > +++ b/drivers/mmc/card/block.c > @@ -66,9 +66,6 @@ MODULE_ALIAS("mmc:block"); > > #define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ > (rq_data_dir(req) == WRITE)) > -#define PACKED_CMD_VER 0x01 > -#define PACKED_CMD_WR 0x02 > - > static DEFINE_MUTEX(block_mutex); > > /* > @@ -102,7 +99,6 @@ struct mmc_blk_data { > unsigned int flags; > #define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ > #define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */ > -#define MMC_BLK_PACKED_CMD (1 << 2) /* MMC packed command support */ > > unsigned int usage; > unsigned int read_only; > @@ -126,12 +122,6 @@ struct mmc_blk_data { > > static DEFINE_MUTEX(open_lock); > > -enum { > - MMC_PACKED_NR_IDX = -1, > - MMC_PACKED_NR_ZERO, > - MMC_PACKED_NR_SINGLE, > -}; > - > module_param(perdev_minors, int, 0444); > MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); > > @@ -139,17 +129,6 @@ static inline int mmc_blk_part_switch(struct mmc_card *card, > struct mmc_blk_data *md); > static int get_card_status(struct mmc_card *card, u32 *status, int retries); > > -static inline void mmc_blk_clear_packed(struct mmc_queue_req *mqrq) > -{ > - struct mmc_packed *packed = mqrq->packed; > - > - mqrq->cmd_type = MMC_PACKED_NONE; > - packed->nr_entries = MMC_PACKED_NR_ZERO; > - packed->idx_failure = MMC_PACKED_NR_IDX; > - packed->retries = 0; > - packed->blocks = 0; > -} > - > static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) > { > struct mmc_blk_data *md; > @@ -1420,111 +1399,12 @@ static enum mmc_blk_status mmc_blk_err_check(struct mmc_card *card, > if (!brq->data.bytes_xfered) > return MMC_BLK_RETRY; > > - if (mmc_packed_cmd(mq_mrq->cmd_type)) { > - if (unlikely(brq->data.blocks << 9 != brq->data.bytes_xfered)) > - return MMC_BLK_PARTIAL; > - else > - return MMC_BLK_SUCCESS; > - } > - > if (blk_rq_bytes(req) != brq->data.bytes_xfered) > return MMC_BLK_PARTIAL; > > return MMC_BLK_SUCCESS; > } > > -static int mmc_packed_init(struct mmc_queue *mq, struct mmc_card *card) > -{ > - struct mmc_queue_req *mqrq_cur = &mq->mqrq[0]; > - struct mmc_queue_req *mqrq_prev = &mq->mqrq[1]; > - int ret = 0; > - > - > - mqrq_cur->packed = kzalloc(sizeof(struct mmc_packed), GFP_KERNEL); > - if (!mqrq_cur->packed) { > - pr_warn("%s: unable to allocate packed cmd for mqrq_cur\n", > - mmc_card_name(card)); > - ret = -ENOMEM; > - goto out; > - } > - > - mqrq_prev->packed = kzalloc(sizeof(struct mmc_packed), GFP_KERNEL); > - if (!mqrq_prev->packed) { > - pr_warn("%s: unable to allocate packed cmd for mqrq_prev\n", > - mmc_card_name(card)); > - kfree(mqrq_cur->packed); > - mqrq_cur->packed = NULL; > - ret = -ENOMEM; > - goto out; > - } > - > - INIT_LIST_HEAD(&mqrq_cur->packed->list); > - INIT_LIST_HEAD(&mqrq_prev->packed->list); > - > -out: > - return ret; > -} > - > -static void mmc_packed_clean(struct mmc_queue *mq) > -{ > - struct mmc_queue_req *mqrq_cur = &mq->mqrq[0]; > - struct mmc_queue_req *mqrq_prev = &mq->mqrq[1]; > - > - kfree(mqrq_cur->packed); > - mqrq_cur->packed = NULL; > - kfree(mqrq_prev->packed); > - mqrq_prev->packed = NULL; > -} > - > -static enum mmc_blk_status mmc_blk_packed_err_check(struct mmc_card *card, > - struct mmc_async_req *areq) > -{ > - struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req, > - mmc_active); > - struct request *req = mq_rq->req; > - struct mmc_packed *packed = mq_rq->packed; > - enum mmc_blk_status status, check; > - int err; > - u8 *ext_csd; > - > - packed->retries--; > - check = mmc_blk_err_check(card, areq); > - err = get_card_status(card, &status, 0); > - if (err) { > - pr_err("%s: error %d sending status command\n", > - req->rq_disk->disk_name, err); > - return MMC_BLK_ABORT; > - } > - > - if (status & R1_EXCEPTION_EVENT) { > - err = mmc_get_ext_csd(card, &ext_csd); > - if (err) { > - pr_err("%s: error %d sending ext_csd\n", > - req->rq_disk->disk_name, err); > - return MMC_BLK_ABORT; > - } > - > - if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] & > - EXT_CSD_PACKED_FAILURE) && > - (ext_csd[EXT_CSD_PACKED_CMD_STATUS] & > - EXT_CSD_PACKED_GENERIC_ERROR)) { > - if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] & > - EXT_CSD_PACKED_INDEXED_ERROR) { > - packed->idx_failure = > - ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] - 1; > - check = MMC_BLK_PARTIAL; > - } > - pr_err("%s: packed cmd failed, nr %u, sectors %u, " > - "failure index: %d\n", > - req->rq_disk->disk_name, packed->nr_entries, > - packed->blocks, packed->idx_failure); > - } > - kfree(ext_csd); > - } > - > - return check; > -} > - > static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, > struct mmc_card *card, > int disable_multi, > @@ -1685,222 +1565,6 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, > mmc_queue_bounce_pre(mqrq); > } > > -static inline u8 mmc_calc_packed_hdr_segs(struct request_queue *q, > - struct mmc_card *card) > -{ > - unsigned int hdr_sz = mmc_large_sector(card) ? 4096 : 512; > - unsigned int max_seg_sz = queue_max_segment_size(q); > - unsigned int len, nr_segs = 0; > - > - do { > - len = min(hdr_sz, max_seg_sz); > - hdr_sz -= len; > - nr_segs++; > - } while (hdr_sz); > - > - return nr_segs; > -} > - > -static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req) > -{ > - struct request_queue *q = mq->queue; > - struct mmc_card *card = mq->card; > - struct request *cur = req, *next = NULL; > - struct mmc_blk_data *md = mq->blkdata; > - struct mmc_queue_req *mqrq = mq->mqrq_cur; > - bool en_rel_wr = card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN; > - unsigned int req_sectors = 0, phys_segments = 0; > - unsigned int max_blk_count, max_phys_segs; > - bool put_back = true; > - u8 max_packed_rw = 0; > - u8 reqs = 0; > - > - /* > - * We don't need to check packed for any further > - * operation of packed stuff as we set MMC_PACKED_NONE > - * and return zero for reqs if geting null packed. Also > - * we clean the flag of MMC_BLK_PACKED_CMD to avoid doing > - * it again when removing blk req. > - */ > - if (!mqrq->packed) { > - md->flags &= (~MMC_BLK_PACKED_CMD); > - goto no_packed; > - } > - > - if (!(md->flags & MMC_BLK_PACKED_CMD)) > - goto no_packed; > - > - if ((rq_data_dir(cur) == WRITE) && > - mmc_host_packed_wr(card->host)) > - max_packed_rw = card->ext_csd.max_packed_writes; > - > - if (max_packed_rw == 0) > - goto no_packed; > - > - if (mmc_req_rel_wr(cur) && > - (md->flags & MMC_BLK_REL_WR) && !en_rel_wr) > - goto no_packed; > - > - if (mmc_large_sector(card) && > - !IS_ALIGNED(blk_rq_sectors(cur), 8)) > - goto no_packed; > - > - mmc_blk_clear_packed(mqrq); > - > - max_blk_count = min(card->host->max_blk_count, > - card->host->max_req_size >> 9); > - if (unlikely(max_blk_count > 0xffff)) > - max_blk_count = 0xffff; > - > - max_phys_segs = queue_max_segments(q); > - req_sectors += blk_rq_sectors(cur); > - phys_segments += cur->nr_phys_segments; > - > - if (rq_data_dir(cur) == WRITE) { > - req_sectors += mmc_large_sector(card) ? 8 : 1; > - phys_segments += mmc_calc_packed_hdr_segs(q, card); > - } > - > - do { > - if (reqs >= max_packed_rw - 1) { > - put_back = false; > - break; > - } > - > - spin_lock_irq(q->queue_lock); > - next = blk_fetch_request(q); > - spin_unlock_irq(q->queue_lock); > - if (!next) { > - put_back = false; > - break; > - } > - > - if (mmc_large_sector(card) && > - !IS_ALIGNED(blk_rq_sectors(next), 8)) > - break; > - > - if (mmc_req_is_special(next)) > - break; > - > - if (rq_data_dir(cur) != rq_data_dir(next)) > - break; > - > - if (mmc_req_rel_wr(next) && > - (md->flags & MMC_BLK_REL_WR) && !en_rel_wr) > - break; > - > - req_sectors += blk_rq_sectors(next); > - if (req_sectors > max_blk_count) > - break; > - > - phys_segments += next->nr_phys_segments; > - if (phys_segments > max_phys_segs) > - break; > - > - list_add_tail(&next->queuelist, &mqrq->packed->list); > - cur = next; > - reqs++; > - } while (1); > - > - if (put_back) { > - spin_lock_irq(q->queue_lock); > - blk_requeue_request(q, next); > - spin_unlock_irq(q->queue_lock); > - } > - > - if (reqs > 0) { > - list_add(&req->queuelist, &mqrq->packed->list); > - mqrq->packed->nr_entries = ++reqs; > - mqrq->packed->retries = reqs; > - return reqs; > - } > - > -no_packed: > - mqrq->cmd_type = MMC_PACKED_NONE; > - return 0; > -} > - > -static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq, > - struct mmc_card *card, > - struct mmc_queue *mq) > -{ > - struct mmc_blk_request *brq = &mqrq->brq; > - struct request *req = mqrq->req; > - struct request *prq; > - struct mmc_blk_data *md = mq->blkdata; > - struct mmc_packed *packed = mqrq->packed; > - bool do_rel_wr, do_data_tag; > - __le32 *packed_cmd_hdr; > - u8 hdr_blocks; > - u8 i = 1; > - > - mqrq->cmd_type = MMC_PACKED_WRITE; > - packed->blocks = 0; > - packed->idx_failure = MMC_PACKED_NR_IDX; > - > - packed_cmd_hdr = packed->cmd_hdr; > - memset(packed_cmd_hdr, 0, sizeof(packed->cmd_hdr)); > - packed_cmd_hdr[0] = cpu_to_le32((packed->nr_entries << 16) | > - (PACKED_CMD_WR << 8) | PACKED_CMD_VER); > - hdr_blocks = mmc_large_sector(card) ? 8 : 1; > - > - /* > - * Argument for each entry of packed group > - */ > - list_for_each_entry(prq, &packed->list, queuelist) { > - do_rel_wr = mmc_req_rel_wr(prq) && (md->flags & MMC_BLK_REL_WR); > - do_data_tag = (card->ext_csd.data_tag_unit_size) && > - (prq->cmd_flags & REQ_META) && > - (rq_data_dir(prq) == WRITE) && > - blk_rq_bytes(prq) >= card->ext_csd.data_tag_unit_size; > - /* Argument of CMD23 */ > - packed_cmd_hdr[(i * 2)] = cpu_to_le32( > - (do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) | > - (do_data_tag ? MMC_CMD23_ARG_TAG_REQ : 0) | > - blk_rq_sectors(prq)); > - /* Argument of CMD18 or CMD25 */ > - packed_cmd_hdr[((i * 2)) + 1] = cpu_to_le32( > - mmc_card_blockaddr(card) ? > - blk_rq_pos(prq) : blk_rq_pos(prq) << 9); > - packed->blocks += blk_rq_sectors(prq); > - i++; > - } > - > - memset(brq, 0, sizeof(struct mmc_blk_request)); > - brq->mrq.cmd = &brq->cmd; > - brq->mrq.data = &brq->data; > - brq->mrq.sbc = &brq->sbc; > - brq->mrq.stop = &brq->stop; > - > - brq->sbc.opcode = MMC_SET_BLOCK_COUNT; > - brq->sbc.arg = MMC_CMD23_ARG_PACKED | (packed->blocks + hdr_blocks); > - brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; > - > - brq->cmd.opcode = MMC_WRITE_MULTIPLE_BLOCK; > - brq->cmd.arg = blk_rq_pos(req); > - if (!mmc_card_blockaddr(card)) > - brq->cmd.arg <<= 9; > - brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; > - > - brq->data.blksz = 512; > - brq->data.blocks = packed->blocks + hdr_blocks; > - brq->data.flags = MMC_DATA_WRITE; > - > - brq->stop.opcode = MMC_STOP_TRANSMISSION; > - brq->stop.arg = 0; > - brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; > - > - mmc_set_data_timeout(&brq->data, card); > - > - brq->data.sg = mqrq->sg; > - brq->data.sg_len = mmc_queue_map_sg(mq, mqrq); > - > - mqrq->mmc_active.mrq = &brq->mrq; > - mqrq->mmc_active.err_check = mmc_blk_packed_err_check; > - > - mmc_queue_bounce_pre(mqrq); > -} > - > static int mmc_blk_cmd_err(struct mmc_blk_data *md, struct mmc_card *card, > struct mmc_blk_request *brq, struct request *req, > int ret) > @@ -1923,79 +1587,10 @@ static int mmc_blk_cmd_err(struct mmc_blk_data *md, struct mmc_card *card, > if (blocks != (u32)-1) { > ret = blk_end_request(req, 0, blocks << 9); > } > - } else { > - if (!mmc_packed_cmd(mq_rq->cmd_type)) > - ret = blk_end_request(req, 0, brq->data.bytes_xfered); > - } > - return ret; > -} > - > -static int mmc_blk_end_packed_req(struct mmc_queue_req *mq_rq) > -{ > - struct request *prq; > - struct mmc_packed *packed = mq_rq->packed; > - int idx = packed->idx_failure, i = 0; > - int ret = 0; > - > - while (!list_empty(&packed->list)) { > - prq = list_entry_rq(packed->list.next); > - if (idx == i) { > - /* retry from error index */ > - packed->nr_entries -= idx; > - mq_rq->req = prq; > - ret = 1; > - > - if (packed->nr_entries == MMC_PACKED_NR_SINGLE) { > - list_del_init(&prq->queuelist); > - mmc_blk_clear_packed(mq_rq); > - } > - return ret; > - } > - list_del_init(&prq->queuelist); > - blk_end_request(prq, 0, blk_rq_bytes(prq)); > - i++; > } > - > - mmc_blk_clear_packed(mq_rq); > return ret; > } > > -static void mmc_blk_abort_packed_req(struct mmc_queue_req *mq_rq) > -{ > - struct request *prq; > - struct mmc_packed *packed = mq_rq->packed; > - > - while (!list_empty(&packed->list)) { > - prq = list_entry_rq(packed->list.next); > - list_del_init(&prq->queuelist); > - blk_end_request(prq, -EIO, blk_rq_bytes(prq)); > - } > - > - mmc_blk_clear_packed(mq_rq); > -} > - > -static void mmc_blk_revert_packed_req(struct mmc_queue *mq, > - struct mmc_queue_req *mq_rq) > -{ > - struct request *prq; > - struct request_queue *q = mq->queue; > - struct mmc_packed *packed = mq_rq->packed; > - > - while (!list_empty(&packed->list)) { > - prq = list_entry_rq(packed->list.prev); > - if (prq->queuelist.prev != &packed->list) { > - list_del_init(&prq->queuelist); > - spin_lock_irq(q->queue_lock); > - blk_requeue_request(mq->queue, prq); > - spin_unlock_irq(q->queue_lock); > - } else { > - list_del_init(&prq->queuelist); > - } > - } > - > - mmc_blk_clear_packed(mq_rq); > -} > - > static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) > { > struct mmc_blk_data *md = mq->blkdata; > @@ -2006,15 +1601,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) > struct mmc_queue_req *mq_rq; > struct request *req = rqc; > struct mmc_async_req *areq; > - const u8 packed_nr = 2; > - u8 reqs = 0; > > if (!rqc && !mq->mqrq_prev->req) > return 0; > > - if (rqc) > - reqs = mmc_blk_prep_packed_list(mq, rqc); > - > do { > if (rqc) { > /* > @@ -2029,11 +1619,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) > goto cmd_abort; > } > > - if (reqs >= packed_nr) > - mmc_blk_packed_hdr_wrq_prep(mq->mqrq_cur, > - card, mq); > - else > - mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); > + mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); > areq = &mq->mqrq_cur->mmc_active; > } else > areq = NULL; > @@ -2058,13 +1644,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) > */ > mmc_blk_reset_success(md, type); > > - if (mmc_packed_cmd(mq_rq->cmd_type)) { > - ret = mmc_blk_end_packed_req(mq_rq); > - break; > - } else { > - ret = blk_end_request(req, 0, > - brq->data.bytes_xfered); > - } > + ret = blk_end_request(req, 0, > + brq->data.bytes_xfered); > > /* > * If the blk_end_request function returns non-zero even > @@ -2101,8 +1682,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) > err = mmc_blk_reset(md, card->host, type); > if (!err) > break; > - if (err == -ENODEV || > - mmc_packed_cmd(mq_rq->cmd_type)) > + if (err == -ENODEV) > goto cmd_abort; > /* Fall through */ > } > @@ -2133,23 +1713,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) > } > > if (ret) { > - if (mmc_packed_cmd(mq_rq->cmd_type)) { > - if (!mq_rq->packed->retries) > - goto cmd_abort; > - mmc_blk_packed_hdr_wrq_prep(mq_rq, card, mq); > - mmc_start_req(card->host, > - &mq_rq->mmc_active, NULL); > - } else { > - > - /* > - * In case of a incomplete request > - * prepare it again and resend. > - */ > - mmc_blk_rw_rq_prep(mq_rq, card, > - disable_multi, mq); > - mmc_start_req(card->host, > - &mq_rq->mmc_active, NULL); > - } > + /* > + * In case of a incomplete request > + * prepare it again and resend. > + */ > + mmc_blk_rw_rq_prep(mq_rq, card, > + disable_multi, mq); > + mmc_start_req(card->host, > + &mq_rq->mmc_active, NULL); > mq_rq->brq.retune_retry_done = retune_retry_done; > } > } while (ret); > @@ -2157,15 +1728,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) > return 1; > > cmd_abort: > - if (mmc_packed_cmd(mq_rq->cmd_type)) { > - mmc_blk_abort_packed_req(mq_rq); > - } else { > - if (mmc_card_removed(card)) > - req->cmd_flags |= REQ_QUIET; > - while (ret) > - ret = blk_end_request(req, -EIO, > - blk_rq_cur_bytes(req)); > - } > + if (mmc_card_removed(card)) > + req->cmd_flags |= REQ_QUIET; > + while (ret) > + ret = blk_end_request(req, -EIO, > + blk_rq_cur_bytes(req)); > > start_new_req: > if (rqc) { > @@ -2173,12 +1740,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) > rqc->cmd_flags |= REQ_QUIET; > blk_end_request_all(rqc, -EIO); > } else { > - /* > - * If current request is packed, it needs to put back. > - */ > - if (mmc_packed_cmd(mq->mqrq_cur->cmd_type)) > - mmc_blk_revert_packed_req(mq, mq->mqrq_cur); > - > mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); > mmc_start_req(card->host, > &mq->mqrq_cur->mmc_active, NULL); > @@ -2361,14 +1922,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, > blk_queue_write_cache(md->queue.queue, true, true); > } > > - if (mmc_card_mmc(card) && > - (area_type == MMC_BLK_DATA_AREA_MAIN) && > - (md->flags & MMC_BLK_CMD23) && > - card->ext_csd.packed_event_en) { > - if (!mmc_packed_init(&md->queue, card)) > - md->flags |= MMC_BLK_PACKED_CMD; > - } > - > return md; > > err_putdisk: > @@ -2472,8 +2025,6 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md) > */ > card = md->queue.card; > mmc_cleanup_queue(&md->queue); > - if (md->flags & MMC_BLK_PACKED_CMD) > - mmc_packed_clean(&md->queue); > if (md->disk->flags & GENHD_FL_UP) { > device_remove_file(disk_to_dev(md->disk), &md->force_ro); > if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && > diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c > index 3f6a2463ab30..7dacf2744fbd 100644 > --- a/drivers/mmc/card/queue.c > +++ b/drivers/mmc/card/queue.c > @@ -406,41 +406,6 @@ void mmc_queue_resume(struct mmc_queue *mq) > } > } > > -static unsigned int mmc_queue_packed_map_sg(struct mmc_queue *mq, > - struct mmc_packed *packed, > - struct scatterlist *sg, > - enum mmc_packed_type cmd_type) > -{ > - struct scatterlist *__sg = sg; > - unsigned int sg_len = 0; > - struct request *req; > - > - if (mmc_packed_wr(cmd_type)) { > - unsigned int hdr_sz = mmc_large_sector(mq->card) ? 4096 : 512; > - unsigned int max_seg_sz = queue_max_segment_size(mq->queue); > - unsigned int len, remain, offset = 0; > - u8 *buf = (u8 *)packed->cmd_hdr; > - > - remain = hdr_sz; > - do { > - len = min(remain, max_seg_sz); > - sg_set_buf(__sg, buf + offset, len); > - offset += len; > - remain -= len; > - sg_unmark_end(__sg++); > - sg_len++; > - } while (remain); > - } > - > - list_for_each_entry(req, &packed->list, queuelist) { > - sg_len += blk_rq_map_sg(mq->queue, req, __sg); > - __sg = sg + (sg_len - 1); > - sg_unmark_end(__sg++); > - } > - sg_mark_end(sg + (sg_len - 1)); > - return sg_len; > -} > - > /* > * Prepare the sg list(s) to be handed of to the host driver > */ > @@ -449,26 +414,14 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq, struct mmc_queue_req *mqrq) > unsigned int sg_len; > size_t buflen; > struct scatterlist *sg; > - enum mmc_packed_type cmd_type; > int i; > > - cmd_type = mqrq->cmd_type; > - > - if (!mqrq->bounce_buf) { > - if (mmc_packed_cmd(cmd_type)) > - return mmc_queue_packed_map_sg(mq, mqrq->packed, > - mqrq->sg, cmd_type); > - else > - return blk_rq_map_sg(mq->queue, mqrq->req, mqrq->sg); > - } > + if (!mqrq->bounce_buf) > + return blk_rq_map_sg(mq->queue, mqrq->req, mqrq->sg); > > BUG_ON(!mqrq->bounce_sg); > > - if (mmc_packed_cmd(cmd_type)) > - sg_len = mmc_queue_packed_map_sg(mq, mqrq->packed, > - mqrq->bounce_sg, cmd_type); > - else > - sg_len = blk_rq_map_sg(mq->queue, mqrq->req, mqrq->bounce_sg); > + sg_len = blk_rq_map_sg(mq->queue, mqrq->req, mqrq->bounce_sg); > > mqrq->bounce_sg_len = sg_len; > > diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h > index 334c9306070f..47f5532b5776 100644 > --- a/drivers/mmc/card/queue.h > +++ b/drivers/mmc/card/queue.h > @@ -22,23 +22,6 @@ struct mmc_blk_request { > int retune_retry_done; > }; > > -enum mmc_packed_type { > - MMC_PACKED_NONE = 0, > - MMC_PACKED_WRITE, > -}; > - > -#define mmc_packed_cmd(type) ((type) != MMC_PACKED_NONE) > -#define mmc_packed_wr(type) ((type) == MMC_PACKED_WRITE) > - > -struct mmc_packed { > - struct list_head list; > - __le32 cmd_hdr[1024]; > - unsigned int blocks; > - u8 nr_entries; > - u8 retries; > - s16 idx_failure; > -}; > - > struct mmc_queue_req { > struct request *req; > struct mmc_blk_request brq; > @@ -47,8 +30,6 @@ struct mmc_queue_req { > struct scatterlist *bounce_sg; > unsigned int bounce_sg_len; > struct mmc_async_req mmc_active; > - enum mmc_packed_type cmd_type; > - struct mmc_packed *packed; > }; > > struct mmc_queue { > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h > index 2a6418d0c343..2ce32fefb41c 100644 > --- a/include/linux/mmc/host.h > +++ b/include/linux/mmc/host.h > @@ -494,11 +494,6 @@ static inline int mmc_host_uhs(struct mmc_host *host) > MMC_CAP_UHS_DDR50); > } > > -static inline int mmc_host_packed_wr(struct mmc_host *host) > -{ > - return host->caps2 & MMC_CAP2_PACKED_WR; > -} > - > static inline int mmc_card_hs(struct mmc_card *card) > { > return card->host->ios.timing == MMC_TIMING_SD_HS || > -- > 2.7.4 > -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html