block.c revision a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Block driver for media (i.e., flash cards)
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2002 Hewlett-Packard Company
5979ce7208a679b8d012450610d5d5aa75aab3af9Pierre Ossman * Copyright 2005-2008 Pierre Ossman
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Use consistent with the GNU GPL is permitted,
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * provided that this copyright notice is
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * preserved in its entirety in all copies and derived works.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FITNESS FOR ANY PARTICULAR PURPOSE.
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Many thanks to Alessandro Rubini and Jonathan Corbet!
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author:  Andrew Christian
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *          28 May 2002
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/moduleparam.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h>
265a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/hdreg.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kdev_t.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/blkdev.h>
31a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven#include <linux/mutex.h>
32ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman#include <linux/scatterlist.h>
33a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman#include <linux/string_helpers.h>
34cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto#include <linux/delay.h>
35cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto#include <linux/capability.h>
36cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto#include <linux/compat.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
38cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto#include <linux/mmc/ioctl.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mmc/card.h>
40385e3227d4d83ab13d7767c4bb3593b0256bf246Pierre Ossman#include <linux/mmc/host.h>
41da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include <linux/mmc/mmc.h>
42da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include <linux/mmc/sd.h>
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/system.h>
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4798ac2162699f7e9880683cb954891817f20b607cPierre Ossman#include "queue.h"
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
496b0b62853b2553be375033776902640320970846Andy WhitcroftMODULE_ALIAS("mmc:block");
505e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson#ifdef MODULE_PARAM_PREFIX
515e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson#undef MODULE_PARAM_PREFIX
525e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson#endif
535e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson#define MODULE_PARAM_PREFIX "mmcblk."
545e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
556a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin#define INAND_CMD38_ARG_EXT_CSD  113
566a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin#define INAND_CMD38_ARG_ERASE    0x00
576a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin#define INAND_CMD38_ARG_TRIM     0x01
586a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin#define INAND_CMD38_ARG_SECERASE 0x80
596a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin#define INAND_CMD38_ARG_SECTRIM1 0x81
606a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin#define INAND_CMD38_ARG_SECTRIM2 0x88
616a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin
625e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonstatic DEFINE_MUTEX(block_mutex);
636b0b62853b2553be375033776902640320970846Andy Whitcroft
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
655e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson * The defaults come from config options but can be overriden by module
665e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson * or bootarg options.
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
685e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonstatic int perdev_minors = CONFIG_MMC_BLOCK_MINORS;
691dff314451fa24d6b107aa05393d3169e56a7e0aDavid Woodhouse
705e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson/*
715e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson * We've only got one major, so number of mmcblk devices is
725e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson * limited to 256 / number of minors per device.
735e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson */
745e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonstatic int max_devices;
755e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
765e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson/* 256 minors, so at most 256 separate devices */
775e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonstatic DECLARE_BITMAP(dev_use, 256);
78f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentinstatic DECLARE_BITMAP(name_use, 256);
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * There is one mmc_blk_data per slot.
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mmc_blk_data {
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spinlock_t	lock;
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct gendisk	*disk;
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_queue queue;
87371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct list_head part;
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
89d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	unsigned int	flags;
90d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin#define MMC_BLK_CMD23	(1 << 0)	/* Can do SET_BLOCK_COUNT for multiblock */
91d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin#define MMC_BLK_REL_WR	(1 << 1)	/* MMC Reliable write support */
92d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int	usage;
94a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	unsigned int	read_only;
95371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	unsigned int	part_type;
96f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	unsigned int	name_idx;
9767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	unsigned int	reset_done;
9867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter#define MMC_BLK_READ		BIT(0)
9967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter#define MMC_BLK_WRITE		BIT(1)
10067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter#define MMC_BLK_DISCARD		BIT(2)
10167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter#define MMC_BLK_SECDISCARD	BIT(3)
102371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
103371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	/*
104371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	 * Only set in main mmc_blk_data associated
105371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	 * with mmc_card with mmc_set_drvdata, and keeps
106371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	 * track of the current selected device partition.
107371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	 */
108371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	unsigned int	part_curr;
109371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct device_attribute force_ro;
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
112a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Venstatic DEFINE_MUTEX(open_lock);
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
114d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlinenum mmc_blk_status {
115d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	MMC_BLK_SUCCESS = 0,
116d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	MMC_BLK_PARTIAL,
117d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	MMC_BLK_CMD_ERR,
11867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	MMC_BLK_RETRY,
119d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	MMC_BLK_ABORT,
12067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	MMC_BLK_DATA_ERR,
12167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	MMC_BLK_ECC_ERR,
122d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin};
123d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
1245e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonmodule_param(perdev_minors, int, 0444);
1255e71b7a64cb4c6cff75ca42b535d8227526ec592Olof JohanssonMODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
1265e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md;
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
131a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven	mutex_lock(&open_lock);
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	md = disk->private_data;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md && md->usage == 0)
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		md = NULL;
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md)
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		md->usage++;
137a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven	mutex_unlock(&open_lock);
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return md;
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
142371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic inline int mmc_get_devidx(struct gendisk *disk)
143371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
144371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	int devmaj = MAJOR(disk_devt(disk));
145371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	int devidx = MINOR(disk_devt(disk)) / perdev_minors;
146371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
147371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (!devmaj)
148371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		devidx = disk->first_minor / perdev_minors;
149371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return devidx;
150371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
151371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mmc_blk_put(struct mmc_blk_data *md)
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
154a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven	mutex_lock(&open_lock);
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	md->usage--;
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md->usage == 0) {
157371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		int devidx = mmc_get_devidx(md->disk);
1585fa83ce284a4b7cd9dcfadd01500b0ed4ab9b740Adrian Hunter		blk_cleanup_queue(md->queue.queue);
1595fa83ce284a4b7cd9dcfadd01500b0ed4ab9b740Adrian Hunter
1601dff314451fa24d6b107aa05393d3169e56a7e0aDavid Woodhouse		__clear_bit(devidx, dev_use);
1611dff314451fa24d6b107aa05393d3169e56a7e0aDavid Woodhouse
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_disk(md->disk);
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(md);
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
165a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven	mutex_unlock(&open_lock);
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
168371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
169371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			     char *buf)
170371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
171371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	int ret;
172371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
173371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
174371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	ret = snprintf(buf, PAGE_SIZE, "%d",
175371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		       get_disk_ro(dev_to_disk(dev)) ^
176371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		       md->read_only);
177371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	mmc_blk_put(md);
178371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return ret;
179371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
180371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
181371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,
182371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			      const char *buf, size_t count)
183371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
184371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	int ret;
185371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	char *end;
186371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
187371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	unsigned long set = simple_strtoul(buf, &end, 0);
188371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (end == buf) {
189371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		ret = -EINVAL;
190371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		goto out;
191371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	}
192371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
193371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	set_disk_ro(dev_to_disk(dev), set || md->read_only);
194371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	ret = count;
195371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinout:
196371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	mmc_blk_put(md);
197371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return ret;
198371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
199371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
200a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Virostatic int mmc_blk_open(struct block_device *bdev, fmode_t mode)
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
202a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro	struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret = -ENXIO;
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2052a48fc0ab24241755dc93bfd4f01d68efab47f5aArnd Bergmann	mutex_lock(&block_mutex);
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md) {
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (md->usage == 2)
208a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro			check_disk_change(bdev);
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = 0;
210a00fc09029f02ca833cf90e5d5625f08c4ac4f51Pierre Ossman
211a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro		if ((mode & FMODE_WRITE) && md->read_only) {
21270bb08962ea9bd50797ae9f16b2493f5f7c65053Andrew Morton			mmc_blk_put(md);
213a00fc09029f02ca833cf90e5d5625f08c4ac4f51Pierre Ossman			ret = -EROFS;
21470bb08962ea9bd50797ae9f16b2493f5f7c65053Andrew Morton		}
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2162a48fc0ab24241755dc93bfd4f01d68efab47f5aArnd Bergmann	mutex_unlock(&block_mutex);
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Virostatic int mmc_blk_release(struct gendisk *disk, fmode_t mode)
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
223a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro	struct mmc_blk_data *md = disk->private_data;
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2252a48fc0ab24241755dc93bfd4f01d68efab47f5aArnd Bergmann	mutex_lock(&block_mutex);
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_blk_put(md);
2272a48fc0ab24241755dc93bfd4f01d68efab47f5aArnd Bergmann	mutex_unlock(&block_mutex);
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
232a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwigmmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
234a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
235a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	geo->heads = 4;
236a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	geo->sectors = 16;
237a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	return 0;
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
240cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixtostruct mmc_blk_ioc_data {
241cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_ioc_cmd ic;
242cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	unsigned char *buf;
243cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	u64 buf_bytes;
244cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto};
245cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
246cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixtostatic struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
247cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_ioc_cmd __user *user)
248cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto{
249cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_blk_ioc_data *idata;
250cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	int err;
251cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
252cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	idata = kzalloc(sizeof(*idata), GFP_KERNEL);
253cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (!idata) {
254cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = -ENOMEM;
255aea253ecffecd38b5ab97edd73fbe2842a7de371Vladimir Motyka		goto out;
256cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
257cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
258cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (copy_from_user(&idata->ic, user, sizeof(idata->ic))) {
259cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = -EFAULT;
260aea253ecffecd38b5ab97edd73fbe2842a7de371Vladimir Motyka		goto idata_err;
261cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
262cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
263cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	idata->buf_bytes = (u64) idata->ic.blksz * idata->ic.blocks;
264cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (idata->buf_bytes > MMC_IOC_MAX_BYTES) {
265cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = -EOVERFLOW;
266aea253ecffecd38b5ab97edd73fbe2842a7de371Vladimir Motyka		goto idata_err;
267cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
268cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
269cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL);
270cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (!idata->buf) {
271cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = -ENOMEM;
272aea253ecffecd38b5ab97edd73fbe2842a7de371Vladimir Motyka		goto idata_err;
273cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
274cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
275cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (copy_from_user(idata->buf, (void __user *)(unsigned long)
276cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto					idata->ic.data_ptr, idata->buf_bytes)) {
277cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = -EFAULT;
278cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		goto copy_err;
279cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
280cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
281cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	return idata;
282cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
283cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixtocopy_err:
284cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	kfree(idata->buf);
285aea253ecffecd38b5ab97edd73fbe2842a7de371Vladimir Motykaidata_err:
286cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	kfree(idata);
287aea253ecffecd38b5ab97edd73fbe2842a7de371Vladimir Motykaout:
288cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	return ERR_PTR(err);
289cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto}
290cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
291cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixtostatic int mmc_blk_ioctl_cmd(struct block_device *bdev,
292cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_ioc_cmd __user *ic_ptr)
293cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto{
294cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_blk_ioc_data *idata;
295cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_blk_data *md;
296cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_card *card;
297cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_command cmd = {0};
298cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct mmc_data data = {0};
299ad5fd97288655b5628052c1fa906419417c86100Venkatraman S	struct mmc_request mrq = {NULL};
300cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	struct scatterlist sg;
301cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	int err;
302cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
303cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	/*
304cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	 * The caller must have CAP_SYS_RAWIO, and must be calling this on the
305cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	 * whole block device, not on a partition.  This prevents overspray
306cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	 * between sibling partitions.
307cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	 */
308cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains))
309cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		return -EPERM;
310cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
311cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	idata = mmc_blk_ioctl_copy_from_user(ic_ptr);
312cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (IS_ERR(idata))
313cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		return PTR_ERR(idata);
314cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
315cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	cmd.opcode = idata->ic.opcode;
316cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	cmd.arg = idata->ic.arg;
317cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	cmd.flags = idata->ic.flags;
318cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
319cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	data.sg = &sg;
320cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	data.sg_len = 1;
321cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	data.blksz = idata->ic.blksz;
322cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	data.blocks = idata->ic.blocks;
323cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
324cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	sg_init_one(data.sg, idata->buf, idata->buf_bytes);
325cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
326cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (idata->ic.write_flag)
327cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		data.flags = MMC_DATA_WRITE;
328cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	else
329cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		data.flags = MMC_DATA_READ;
330cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
331cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	mrq.cmd = &cmd;
332cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	mrq.data = &data;
333cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
334cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	md = mmc_blk_get(bdev->bd_disk);
335cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (!md) {
336cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = -EINVAL;
337cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		goto cmd_done;
338cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
339cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
340cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	card = md->queue.card;
341cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (IS_ERR(card)) {
342cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = PTR_ERR(card);
343cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		goto cmd_done;
344cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
345cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
346cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	mmc_claim_host(card->host);
347cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
348cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (idata->ic.is_acmd) {
349cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = mmc_app_cmd(card->host, card);
350cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		if (err)
351cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto			goto cmd_rel_host;
352cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
353cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
354cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	/* data.flags must already be set before doing this. */
355cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	mmc_set_data_timeout(&data, card);
356cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	/* Allow overriding the timeout_ns for empirical tuning. */
357cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (idata->ic.data_timeout_ns)
358cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		data.timeout_ns = idata->ic.data_timeout_ns;
359cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
360cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
361cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		/*
362cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		 * Pretend this is a data transfer and rely on the host driver
363cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		 * to compute timeout.  When all host drivers support
364cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		 * cmd.cmd_timeout for R1B, this can be changed to:
365cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		 *
366cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		 *     mrq.data = NULL;
367cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		 *     cmd.cmd_timeout = idata->ic.cmd_timeout_ms;
368cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		 */
369cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000;
370cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
371cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
372cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	mmc_wait_for_req(card->host, &mrq);
373cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
374cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (cmd.error) {
375cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		dev_err(mmc_dev(card->host), "%s: cmd error %d\n",
376cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto						__func__, cmd.error);
377cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = cmd.error;
378cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		goto cmd_rel_host;
379cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
380cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (data.error) {
381cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		dev_err(mmc_dev(card->host), "%s: data error %d\n",
382cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto						__func__, data.error);
383cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = data.error;
384cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		goto cmd_rel_host;
385cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
386cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
387cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	/*
388cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	 * According to the SD specs, some commands require a delay after
389cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	 * issuing the command.
390cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	 */
391cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (idata->ic.postsleep_min_us)
392cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us);
393cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
394cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (copy_to_user(&(ic_ptr->response), cmd.resp, sizeof(cmd.resp))) {
395cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		err = -EFAULT;
396cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		goto cmd_rel_host;
397cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
398cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
399cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (!idata->ic.write_flag) {
400cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		if (copy_to_user((void __user *)(unsigned long) idata->ic.data_ptr,
401cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto						idata->buf, idata->buf_bytes)) {
402cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto			err = -EFAULT;
403cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto			goto cmd_rel_host;
404cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		}
405cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	}
406cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
407cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixtocmd_rel_host:
408cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	mmc_release_host(card->host);
409cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
410cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixtocmd_done:
411cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	mmc_blk_put(md);
412cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	kfree(idata->buf);
413cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	kfree(idata);
414cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	return err;
415cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto}
416cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
417cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixtostatic int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
418cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	unsigned int cmd, unsigned long arg)
419cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto{
420cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	int ret = -EINVAL;
421cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	if (cmd == MMC_IOC_CMD)
422cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto		ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg);
423cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	return ret;
424cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto}
425cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
426cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto#ifdef CONFIG_COMPAT
427cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixtostatic int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
428cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	unsigned int cmd, unsigned long arg)
429cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto{
430cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	return mmc_blk_ioctl(bdev, mode, cmd, (unsigned long) compat_ptr(arg));
431cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto}
432cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto#endif
433cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto
43483d5cde47dedf01b6a4a4331882cbc0a7eea3c2eAlexey Dobriyanstatic const struct block_device_operations mmc_bdops = {
435a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro	.open			= mmc_blk_open,
436a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro	.release		= mmc_blk_release,
437a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	.getgeo			= mmc_blk_getgeo,
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.owner			= THIS_MODULE,
439cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	.ioctl			= mmc_blk_ioctl,
440cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto#ifdef CONFIG_COMPAT
441cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto	.compat_ioctl		= mmc_blk_compat_ioctl,
442cb87ea28ed9e75a41eb456bfcb547b4e6f10e750John Calixto#endif
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
445371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic inline int mmc_blk_part_switch(struct mmc_card *card,
446371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin				      struct mmc_blk_data *md)
447371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
448371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	int ret;
449371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *main_md = mmc_get_drvdata(card);
4500d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter
451371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (main_md->part_curr == md->part_type)
452371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		return 0;
453371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
454371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (mmc_card_mmc(card)) {
4550d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter		u8 part_config = card->ext_csd.part_config;
4560d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter
4570d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter		part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
4580d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter		part_config |= md->part_type;
459371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
460371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
4610d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter				 EXT_CSD_PART_CONFIG, part_config,
462371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin				 card->ext_csd.part_time);
463371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		if (ret)
464371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			return ret;
4650d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter
4660d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter		card->ext_csd.part_config = part_config;
46767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	}
468371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
469371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	main_md->part_curr = md->part_type;
470371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return 0;
471371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
472371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
473ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossmanstatic u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
474ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman{
475ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	int err;
476051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	u32 result;
477051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	__be32 *blocks;
478ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
479ad5fd97288655b5628052c1fa906419417c86100Venkatraman S	struct mmc_request mrq = {NULL};
4801278dba167f01bb3c6626d16450d31129d041087Chris Ball	struct mmc_command cmd = {0};
481a61ad2b49bfce94dfddce828cd9222e4b9e7825bChris Ball	struct mmc_data data = {0};
482ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	unsigned int timeout_us;
483ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
484ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	struct scatterlist sg;
485ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
486ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	cmd.opcode = MMC_APP_CMD;
487ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	cmd.arg = card->rca << 16;
4887213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
489ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
490ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	err = mmc_wait_for_cmd(card->host, &cmd, 0);
4917213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell	if (err)
4927213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell		return (u32)-1;
4937213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell	if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
494ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		return (u32)-1;
495ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
496ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	memset(&cmd, 0, sizeof(struct mmc_command));
497ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
498ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	cmd.opcode = SD_APP_SEND_NUM_WR_BLKS;
499ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	cmd.arg = 0;
5007213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
501ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
502ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.timeout_ns = card->csd.tacc_ns * 100;
503ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.timeout_clks = card->csd.tacc_clks * 100;
504ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
505ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	timeout_us = data.timeout_ns / 1000;
506ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	timeout_us += data.timeout_clks * 1000 /
507ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		(card->host->ios.clock / 1000);
508ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
509ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	if (timeout_us > 100000) {
510ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		data.timeout_ns = 100000000;
511ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		data.timeout_clks = 0;
512ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	}
513ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
514ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.blksz = 4;
515ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.blocks = 1;
516ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.flags = MMC_DATA_READ;
517ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.sg = &sg;
518ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.sg_len = 1;
519ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
520ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	mrq.cmd = &cmd;
521ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	mrq.data = &data;
522ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
523051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	blocks = kmalloc(4, GFP_KERNEL);
524051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	if (!blocks)
525051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks		return (u32)-1;
526051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks
527051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	sg_init_one(&sg, blocks, 4);
528ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
529ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	mmc_wait_for_req(card->host, &mrq);
530ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
531051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	result = ntohl(*blocks);
532051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	kfree(blocks);
533051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks
53417b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman	if (cmd.error || data.error)
535051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks		result = (u32)-1;
536ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
537051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	return result;
538ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman}
539ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
540a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linuxstatic int send_stop(struct mmc_card *card, u32 *status)
541a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux{
542a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	struct mmc_command cmd = {0};
543a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	int err;
544a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
545a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	cmd.opcode = MMC_STOP_TRANSMISSION;
546a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
547a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	err = mmc_wait_for_cmd(card->host, &cmd, 5);
548a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	if (err == 0)
549a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		*status = cmd.resp[0];
550a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	return err;
551a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux}
552a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
5530a2d4048a22079d7e79d6654bbacbef57bd5728aRussell King - ARM Linuxstatic int get_card_status(struct mmc_card *card, u32 *status, int retries)
554504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter{
5551278dba167f01bb3c6626d16450d31129d041087Chris Ball	struct mmc_command cmd = {0};
556504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	int err;
557504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter
558504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	cmd.opcode = MMC_SEND_STATUS;
559504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	if (!mmc_host_is_spi(card->host))
560504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter		cmd.arg = card->rca << 16;
561504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
5620a2d4048a22079d7e79d6654bbacbef57bd5728aRussell King - ARM Linux	err = mmc_wait_for_cmd(card->host, &cmd, retries);
5630a2d4048a22079d7e79d6654bbacbef57bd5728aRussell King - ARM Linux	if (err == 0)
5640a2d4048a22079d7e79d6654bbacbef57bd5728aRussell King - ARM Linux		*status = cmd.resp[0];
5650a2d4048a22079d7e79d6654bbacbef57bd5728aRussell King - ARM Linux	return err;
566504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter}
567504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter
568a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux#define ERR_RETRY	2
569a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux#define ERR_ABORT	1
570a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux#define ERR_CONTINUE	0
571a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
572a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linuxstatic int mmc_blk_cmd_error(struct request *req, const char *name, int error,
573a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	bool status_valid, u32 status)
574a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux{
575a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	switch (error) {
576a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	case -EILSEQ:
577a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		/* response crc error, retry the r/w cmd */
578a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		pr_err("%s: %s sending %s command, card status %#x\n",
579a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			req->rq_disk->disk_name, "response CRC error",
580a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			name, status);
581a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		return ERR_RETRY;
582a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
583a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	case -ETIMEDOUT:
584a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		pr_err("%s: %s sending %s command, card status %#x\n",
585a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			req->rq_disk->disk_name, "timed out", name, status);
586a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
587a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		/* If the status cmd initially failed, retry the r/w cmd */
588a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		if (!status_valid)
589a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			return ERR_RETRY;
590a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
591a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		/*
592a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		 * If it was a r/w cmd crc error, or illegal command
593a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		 * (eg, issued in wrong state) then retry - we should
594a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		 * have corrected the state problem above.
595a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		 */
596a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		if (status & (R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND))
597a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			return ERR_RETRY;
598a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
599a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		/* Otherwise abort the command */
600a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		return ERR_ABORT;
601a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
602a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	default:
603a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		/* We don't understand the error code the driver gave us */
604a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		pr_err("%s: unknown error %d sending read/write command, card status %#x\n",
605a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		       req->rq_disk->disk_name, error, status);
606a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		return ERR_ABORT;
607a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	}
608a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux}
609a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
610a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux/*
611a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * Initial r/w and stop cmd error recovery.
612a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * We don't know whether the card received the r/w cmd or not, so try to
613a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * restore things back to a sane state.  Essentially, we do this as follows:
614a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * - Obtain card status.  If the first attempt to obtain card status fails,
615a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux *   the status word will reflect the failed status cmd, not the failed
616a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux *   r/w cmd.  If we fail to obtain card status, it suggests we can no
617a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux *   longer communicate with the card.
618a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * - Check the card state.  If the card received the cmd but there was a
619a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux *   transient problem with the response, it might still be in a data transfer
620a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux *   mode.  Try to send it a stop command.  If this fails, we can't recover.
621a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * - If the r/w cmd failed due to a response CRC error, it was probably
622a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux *   transient, so retry the cmd.
623a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * - If the r/w cmd timed out, but we didn't get the r/w cmd status, retry.
624a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * - If the r/w cmd timed out, and the r/w cmd failed due to CRC error or
625a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux *   illegal cmd, retry.
626a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux * Otherwise we don't understand what happened, so abort.
627a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux */
628a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linuxstatic int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
62967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	struct mmc_blk_request *brq, int *ecc_err)
630a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux{
631a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	bool prev_cmd_status_valid = true;
632a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	u32 status, stop_status = 0;
633a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	int err, retry;
634a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
635a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	/*
636a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 * Try to get card status which indicates both the card state
637a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 * and why there was no response.  If the first attempt fails,
638a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 * we can't be sure the returned status is for the r/w command.
639a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 */
640a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	for (retry = 2; retry >= 0; retry--) {
641a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		err = get_card_status(card, &status, 0);
642a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		if (!err)
643a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			break;
644a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
645a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		prev_cmd_status_valid = false;
646a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		pr_err("%s: error %d sending status command, %sing\n",
647a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		       req->rq_disk->disk_name, err, retry ? "retry" : "abort");
648a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	}
649a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
650a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	/* We couldn't get a response from the card.  Give up. */
651a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	if (err)
652a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		return ERR_ABORT;
653a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
65467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	/* Flag ECC errors */
65567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if ((status & R1_CARD_ECC_FAILED) ||
65667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	    (brq->stop.resp[0] & R1_CARD_ECC_FAILED) ||
65767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	    (brq->cmd.resp[0] & R1_CARD_ECC_FAILED))
65867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		*ecc_err = 1;
65967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
660a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	/*
661a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 * Check the current card state.  If it is in some data transfer
662a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 * mode, tell it to stop (and hopefully transition back to TRAN.)
663a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 */
664a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	if (R1_CURRENT_STATE(status) == R1_STATE_DATA ||
665a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	    R1_CURRENT_STATE(status) == R1_STATE_RCV) {
666a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		err = send_stop(card, &stop_status);
667a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		if (err)
668a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			pr_err("%s: error %d sending stop command\n",
669a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			       req->rq_disk->disk_name, err);
670a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
671a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		/*
672a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		 * If the stop cmd also timed out, the card is probably
673a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		 * not present, so abort.  Other errors are bad news too.
674a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		 */
675a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		if (err)
676a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux			return ERR_ABORT;
67767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		if (stop_status & R1_CARD_ECC_FAILED)
67867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			*ecc_err = 1;
679a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	}
680a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
681a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	/* Check for set block count errors */
682a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	if (brq->sbc.error)
683a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		return mmc_blk_cmd_error(req, "SET_BLOCK_COUNT", brq->sbc.error,
684a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux				prev_cmd_status_valid, status);
685a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
686a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	/* Check for r/w command errors */
687a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	if (brq->cmd.error)
688a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		return mmc_blk_cmd_error(req, "r/w cmd", brq->cmd.error,
689a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux				prev_cmd_status_valid, status);
690a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
69167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	/* Data errors */
69267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (!brq->stop.error)
69367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		return ERR_CONTINUE;
69467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
695a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	/* Now for stop errors.  These aren't fatal to the transfer. */
696a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	pr_err("%s: error %d sending stop command, original cmd response %#x, card status %#x\n",
697a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	       req->rq_disk->disk_name, brq->stop.error,
698a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	       brq->cmd.resp[0], status);
699a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
700a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	/*
701a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 * Subsitute in our own stop status as this will give the error
702a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 * state which happened during the execution of the r/w command.
703a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	 */
704a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	if (stop_status) {
705a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		brq->stop.resp[0] = stop_status;
706a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux		brq->stop.error = 0;
707a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	}
708a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux	return ERR_CONTINUE;
709a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux}
710a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux
71167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunterstatic int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
71267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 int type)
71367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter{
71467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	int err;
71567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
71667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (md->reset_done & type)
71767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		return -EEXIST;
71867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
71967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	md->reset_done |= type;
72067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	err = mmc_hw_reset(host);
72167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	/* Ensure we switch back to the correct partition */
72267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (err != -EOPNOTSUPP) {
72367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		struct mmc_blk_data *main_md = mmc_get_drvdata(host->card);
72467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		int part_err;
72567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
72667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		main_md->part_curr = main_md->part_type;
72767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		part_err = mmc_blk_part_switch(host->card, md);
72867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		if (part_err) {
72967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			/*
73067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 * We have failed to get back into the correct
73167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 * partition, so we need to abort the whole request.
73267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 */
73367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			return -ENODEV;
73467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		}
73567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	}
73667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	return err;
73767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter}
73867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
73967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunterstatic inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type)
74067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter{
74167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	md->reset_done &= ~type;
74267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter}
74367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
744bd788c9665fb7c543aac21317059375632343337Adrian Hunterstatic int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
745bd788c9665fb7c543aac21317059375632343337Adrian Hunter{
746bd788c9665fb7c543aac21317059375632343337Adrian Hunter	struct mmc_blk_data *md = mq->data;
747bd788c9665fb7c543aac21317059375632343337Adrian Hunter	struct mmc_card *card = md->queue.card;
748bd788c9665fb7c543aac21317059375632343337Adrian Hunter	unsigned int from, nr, arg;
74967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	int err = 0, type = MMC_BLK_DISCARD;
750bd788c9665fb7c543aac21317059375632343337Adrian Hunter
751bd788c9665fb7c543aac21317059375632343337Adrian Hunter	if (!mmc_can_erase(card)) {
752bd788c9665fb7c543aac21317059375632343337Adrian Hunter		err = -EOPNOTSUPP;
753bd788c9665fb7c543aac21317059375632343337Adrian Hunter		goto out;
754bd788c9665fb7c543aac21317059375632343337Adrian Hunter	}
755bd788c9665fb7c543aac21317059375632343337Adrian Hunter
756bd788c9665fb7c543aac21317059375632343337Adrian Hunter	from = blk_rq_pos(req);
757bd788c9665fb7c543aac21317059375632343337Adrian Hunter	nr = blk_rq_sectors(req);
758bd788c9665fb7c543aac21317059375632343337Adrian Hunter
759bd788c9665fb7c543aac21317059375632343337Adrian Hunter	if (mmc_can_trim(card))
760bd788c9665fb7c543aac21317059375632343337Adrian Hunter		arg = MMC_TRIM_ARG;
761bd788c9665fb7c543aac21317059375632343337Adrian Hunter	else
762bd788c9665fb7c543aac21317059375632343337Adrian Hunter		arg = MMC_ERASE_ARG;
76367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunterretry:
7646a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	if (card->quirks & MMC_QUIRK_INAND_CMD38) {
7656a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
7666a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 INAND_CMD38_ARG_EXT_CSD,
7676a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 arg == MMC_TRIM_ARG ?
7686a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 INAND_CMD38_ARG_TRIM :
7696a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 INAND_CMD38_ARG_ERASE,
7706a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 0);
7716a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin		if (err)
7726a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin			goto out;
7736a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	}
774bd788c9665fb7c543aac21317059375632343337Adrian Hunter	err = mmc_erase(card, from, nr, arg);
775bd788c9665fb7c543aac21317059375632343337Adrian Hunterout:
77667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (err == -EIO && !mmc_blk_reset(md, card->host, type))
77767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		goto retry;
77867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (!err)
77967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		mmc_blk_reset_success(md, type);
780bd788c9665fb7c543aac21317059375632343337Adrian Hunter	spin_lock_irq(&md->lock);
781bd788c9665fb7c543aac21317059375632343337Adrian Hunter	__blk_end_request(req, err, blk_rq_bytes(req));
782bd788c9665fb7c543aac21317059375632343337Adrian Hunter	spin_unlock_irq(&md->lock);
783bd788c9665fb7c543aac21317059375632343337Adrian Hunter
784bd788c9665fb7c543aac21317059375632343337Adrian Hunter	return err ? 0 : 1;
785bd788c9665fb7c543aac21317059375632343337Adrian Hunter}
786bd788c9665fb7c543aac21317059375632343337Adrian Hunter
7874980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunterstatic int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
7884980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter				       struct request *req)
7894980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter{
7904980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	struct mmc_blk_data *md = mq->data;
7914980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	struct mmc_card *card = md->queue.card;
7924980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	unsigned int from, nr, arg;
79367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	int err = 0, type = MMC_BLK_SECDISCARD;
7944980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
7954980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	if (!mmc_can_secure_erase_trim(card)) {
7964980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		err = -EOPNOTSUPP;
7974980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		goto out;
7984980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	}
7994980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
8004980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	from = blk_rq_pos(req);
8014980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	nr = blk_rq_sectors(req);
8024980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
8034980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
8044980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		arg = MMC_SECURE_TRIM1_ARG;
8054980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	else
8064980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		arg = MMC_SECURE_ERASE_ARG;
80767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunterretry:
8086a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	if (card->quirks & MMC_QUIRK_INAND_CMD38) {
8096a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
8106a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 INAND_CMD38_ARG_EXT_CSD,
8116a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 arg == MMC_SECURE_TRIM1_ARG ?
8126a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 INAND_CMD38_ARG_SECTRIM1 :
8136a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 INAND_CMD38_ARG_SECERASE,
8146a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				 0);
8156a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin		if (err)
8166a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin			goto out;
8176a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	}
8184980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	err = mmc_erase(card, from, nr, arg);
8196a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	if (!err && arg == MMC_SECURE_TRIM1_ARG) {
8206a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin		if (card->quirks & MMC_QUIRK_INAND_CMD38) {
8216a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
8226a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin					 INAND_CMD38_ARG_EXT_CSD,
8236a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin					 INAND_CMD38_ARG_SECTRIM2,
8246a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin					 0);
8256a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin			if (err)
8266a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin				goto out;
8276a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin		}
8284980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
8296a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	}
8304980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunterout:
83167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (err == -EIO && !mmc_blk_reset(md, card->host, type))
83267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		goto retry;
83367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (!err)
83467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		mmc_blk_reset_success(md, type);
8354980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	spin_lock_irq(&md->lock);
8364980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	__blk_end_request(req, err, blk_rq_bytes(req));
8374980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	spin_unlock_irq(&md->lock);
8384980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
8394980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	return err ? 0 : 1;
8404980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter}
8414980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
842f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentinstatic int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
843f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin{
844f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	struct mmc_blk_data *md = mq->data;
845f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin
846f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	/*
847f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	 * No-op, only service this because we need REQ_FUA for reliable
848f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	 * writes.
849f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	 */
850f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	spin_lock_irq(&md->lock);
851f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	__blk_end_request_all(req, 0);
852f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	spin_unlock_irq(&md->lock);
853f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin
854f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	return 1;
855f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin}
856f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin
857f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin/*
858f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin * Reformat current write as a reliable write, supporting
859f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin * both legacy and the enhanced reliable write MMC cards.
860f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin * In each transfer we'll handle only as much as a single
861f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin * reliable write can handle, thus finish the request in
862f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin * partial completions.
863f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin */
864d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentinstatic inline void mmc_apply_rel_rw(struct mmc_blk_request *brq,
865d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin				    struct mmc_card *card,
866d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin				    struct request *req)
867f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin{
868f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	if (!(card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN)) {
869f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin		/* Legacy mode imposes restrictions on transfers. */
870f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin		if (!IS_ALIGNED(brq->cmd.arg, card->ext_csd.rel_sectors))
871f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin			brq->data.blocks = 1;
872f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin
873f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin		if (brq->data.blocks > card->ext_csd.rel_sectors)
874f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin			brq->data.blocks = card->ext_csd.rel_sectors;
875f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin		else if (brq->data.blocks < card->ext_csd.rel_sectors)
876f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin			brq->data.blocks = 1;
877f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	}
878f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin}
879f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin
8804c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux#define CMD_ERRORS							\
8814c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux	(R1_OUT_OF_RANGE |	/* Command argument out of range */	\
8824c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux	 R1_ADDRESS_ERROR |	/* Misaligned address */		\
8834c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux	 R1_BLOCK_LEN_ERROR |	/* Transferred block length incorrect */\
8844c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux	 R1_WP_VIOLATION |	/* Tried to write to protected block */	\
8854c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux	 R1_CC_ERROR |		/* Card controller error */		\
8864c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux	 R1_ERROR)		/* General/unknown error */
8874c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux
888ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlinstatic int mmc_blk_err_check(struct mmc_card *card,
889ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			     struct mmc_async_req *areq)
890d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin{
891ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req,
892ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin						    mmc_active);
893ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	struct mmc_blk_request *brq = &mq_mrq->brq;
894ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	struct request *req = mq_mrq->req;
89567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	int ecc_err = 0;
896d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
897d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	/*
898d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * sbc.error indicates a problem with the set block count
899d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * command.  No data will have been transferred.
900d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 *
901d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * cmd.error indicates a problem with the r/w command.  No
902d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * data will have been transferred.
903d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 *
904d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * stop.error indicates a problem with the stop command.  Data
905d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * may have been transferred, or may still be transferring.
906d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 */
90767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (brq->sbc.error || brq->cmd.error || brq->stop.error ||
90867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	    brq->data.error) {
90967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err)) {
910d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		case ERR_RETRY:
911d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			return MMC_BLK_RETRY;
912d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		case ERR_ABORT:
913d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			return MMC_BLK_ABORT;
914d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		case ERR_CONTINUE:
915d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			break;
916d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		}
917d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	}
918d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
919d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	/*
920d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * Check for errors relating to the execution of the
921d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * initial command - such as address errors.  No data
922d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * has been transferred.
923d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 */
924d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	if (brq->cmd.resp[0] & CMD_ERRORS) {
925d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		pr_err("%s: r/w command failed, status = %#x\n",
926d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		       req->rq_disk->disk_name, brq->cmd.resp[0]);
927d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		return MMC_BLK_ABORT;
928d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	}
929d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
930d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	/*
931d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * Everything else is either success, or a data error of some
932d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * kind.  If it was a write, we may have transitioned to
933d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 * program mode, which we have to wait for it to complete.
934d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	 */
935d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
936d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		u32 status;
937d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		do {
938d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			int err = get_card_status(card, &status, 5);
939d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			if (err) {
940a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S				pr_err("%s: error %d requesting status\n",
941d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin				       req->rq_disk->disk_name, err);
942d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin				return MMC_BLK_CMD_ERR;
943d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			}
944d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			/*
945d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 * Some cards mishandle the status bits,
946d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 * so make sure to check both the busy
947d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 * indication and the card state.
948d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 */
949d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		} while (!(status & R1_READY_FOR_DATA) ||
950d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 (R1_CURRENT_STATE(status) == R1_STATE_PRG));
951d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	}
952d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
953d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	if (brq->data.error) {
954d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n",
955d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		       req->rq_disk->disk_name, brq->data.error,
956d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		       (unsigned)blk_rq_pos(req),
957d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		       (unsigned)blk_rq_sectors(req),
958d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		       brq->cmd.resp[0], brq->stop.resp[0]);
959d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
960d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		if (rq_data_dir(req) == READ) {
96167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			if (ecc_err)
96267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				return MMC_BLK_ECC_ERR;
963d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			return MMC_BLK_DATA_ERR;
964d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		} else {
965d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			return MMC_BLK_CMD_ERR;
966d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		}
967d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	}
968d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
96967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (!brq->data.bytes_xfered)
97067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		return MMC_BLK_RETRY;
971d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
97267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (blk_rq_bytes(req) != brq->data.bytes_xfered)
97367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		return MMC_BLK_PARTIAL;
97467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
97567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	return MMC_BLK_SUCCESS;
976d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin}
977d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin
97854d49d77628bed77e5491b8a2a1158a492843a19Per Forlinstatic void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
97954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin			       struct mmc_card *card,
98054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin			       int disable_multi,
98154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin			       struct mmc_queue *mq)
9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
98354d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	u32 readcmd, writecmd;
98454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	struct mmc_blk_request *brq = &mqrq->brq;
98554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	struct request *req = mqrq->req;
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md = mq->data;
9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
988f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	/*
989f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	 * Reliable writes are used to implement Forced Unit Access and
990f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	 * REQ_META accesses, and are supported only on MMCs.
99165299a3b788bd274bed92f9fa3232082c9f3ea70Christoph Hellwig	 *
99265299a3b788bd274bed92f9fa3232082c9f3ea70Christoph Hellwig	 * XXX: this really needs a good explanation of why REQ_META
99365299a3b788bd274bed92f9fa3232082c9f3ea70Christoph Hellwig	 * is treated special.
994f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	 */
995f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin	bool do_rel_wr = ((req->cmd_flags & REQ_FUA) ||
996f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin			  (req->cmd_flags & REQ_META)) &&
997f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin		(rq_data_dir(req) == WRITE) &&
998d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin		(md->flags & MMC_BLK_REL_WR);
999f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin
100054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	memset(brq, 0, sizeof(struct mmc_blk_request));
100154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->mrq.cmd = &brq->cmd;
100254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->mrq.data = &brq->data;
10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
100454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->cmd.arg = blk_rq_pos(req);
100554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	if (!mmc_card_blockaddr(card))
100654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->cmd.arg <<= 9;
100754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
100854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->data.blksz = 512;
100954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->stop.opcode = MMC_STOP_TRANSMISSION;
101054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->stop.arg = 0;
101154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
101254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->data.blocks = blk_rq_sectors(req);
10136a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter
101454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	/*
101554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * The block layer doesn't support all sector count
101654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * restrictions, so we need to be prepared for too big
101754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * requests.
101854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 */
101954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	if (brq->data.blocks > card->host->max_blk_count)
102054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->data.blocks = card->host->max_blk_count;
10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
102254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	/*
102354d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * After a read error, we redo the request one sector at a time
102454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * in order to accurately determine which sectors can be read
102554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * successfully.
102654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 */
102754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	if (disable_multi && brq->data.blocks > 1)
102854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->data.blocks = 1;
1029d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin
103054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	if (brq->data.blocks > 1 || do_rel_wr) {
103154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		/* SPI multiblock writes terminate using a special
103254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		 * token, not a STOP_TRANSMISSION request.
1033d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin		 */
103454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		if (!mmc_host_is_spi(card->host) ||
103554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		    rq_data_dir(req) == READ)
103654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin			brq->mrq.stop = &brq->stop;
103754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		readcmd = MMC_READ_MULTIPLE_BLOCK;
103854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		writecmd = MMC_WRITE_MULTIPLE_BLOCK;
103954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	} else {
104054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->mrq.stop = NULL;
104154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		readcmd = MMC_READ_SINGLE_BLOCK;
104254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		writecmd = MMC_WRITE_BLOCK;
104354d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	}
104454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	if (rq_data_dir(req) == READ) {
104554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->cmd.opcode = readcmd;
104654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->data.flags |= MMC_DATA_READ;
104754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	} else {
104854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->cmd.opcode = writecmd;
104954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->data.flags |= MMC_DATA_WRITE;
105054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	}
1051d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin
105254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	if (do_rel_wr)
105354d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		mmc_apply_rel_rw(brq, card, req);
1054f4c5522b0a8827f39f83f928961d87e081bfe71cAndrei Warkentin
105554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	/*
105654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * Pre-defined multi-block transfers are preferable to
105754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * open ended-ones (and necessary for reliable writes).
105854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * However, it is not sufficient to just send CMD23,
105954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * and avoid the final CMD12, as on an error condition
106054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * CMD12 (stop) needs to be sent anyway. This, coupled
106154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * with Auto-CMD23 enhancements provided by some
106254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * hosts, means that the complexity of dealing
106354d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * with this is best left to the host. If CMD23 is
106454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * supported by card and host, we'll fill sbc in and let
106554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * the host deal with handling it correctly. This means
106654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * that for hosts that don't expose MMC_CAP_CMD23, no
106754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * change of behavior will be observed.
106854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 *
106954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * N.B: Some MMC cards experience perf degradation.
107054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * We'll avoid using CMD23-bounded multiblock writes for
107154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * these, while retaining features like reliable writes.
107254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 */
1073b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossman
107454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	if ((md->flags & MMC_BLK_CMD23) &&
107554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	    mmc_op_multi(brq->cmd.opcode) &&
107654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	    (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
107754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
107854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->sbc.arg = brq->data.blocks |
107954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin			(do_rel_wr ? (1 << 31) : 0);
108054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
108154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->mrq.sbc = &brq->sbc;
108254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	}
108398ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman
108454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	mmc_set_data_timeout(&brq->data, card);
108554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin
108654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->data.sg = mqrq->sg;
108754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	brq->data.sg_len = mmc_queue_map_sg(mq, mqrq);
108854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin
108954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	/*
109054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * Adjust the sg list so it is the same size as the
109154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 * request.
109254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	 */
109354d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	if (brq->data.blocks != blk_rq_sectors(req)) {
109454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		int i, data_size = brq->data.blocks << 9;
109554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		struct scatterlist *sg;
109654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin
109754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		for_each_sg(brq->data.sg, sg, brq->data.sg_len, i) {
109854d49d77628bed77e5491b8a2a1158a492843a19Per Forlin			data_size -= sg->length;
109954d49d77628bed77e5491b8a2a1158a492843a19Per Forlin			if (data_size <= 0) {
110054d49d77628bed77e5491b8a2a1158a492843a19Per Forlin				sg->length += data_size;
110154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin				i++;
110254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin				break;
11036a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			}
11046a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		}
110554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin		brq->data.sg_len = i;
110654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	}
110754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin
1108ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	mqrq->mmc_active.mrq = &brq->mrq;
1109ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	mqrq->mmc_active.err_check = mmc_blk_err_check;
1110ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin
111154d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	mmc_queue_bounce_pre(mqrq);
111254d49d77628bed77e5491b8a2a1158a492843a19Per Forlin}
11136a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter
111467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunterstatic int mmc_blk_cmd_err(struct mmc_blk_data *md, struct mmc_card *card,
111567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			   struct mmc_blk_request *brq, struct request *req,
111667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			   int ret)
111767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter{
111867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	/*
111967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	 * If this is an SD card and we're writing, we can first
112067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	 * mark the known good sectors as ok.
112167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	 *
112267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	 * If the card is not SD, we can still ok written sectors
112367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	 * as reported by the controller (which might be less than
112467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	 * the real number of written sectors, but never more).
112567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	 */
112667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	if (mmc_card_sd(card)) {
112767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		u32 blocks;
112867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
112967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		blocks = mmc_sd_num_wr_blocks(card);
113067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		if (blocks != (u32)-1) {
113167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			spin_lock_irq(&md->lock);
113267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			ret = __blk_end_request(req, 0, blocks << 9);
113367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			spin_unlock_irq(&md->lock);
113467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		}
113567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	} else {
113667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		spin_lock_irq(&md->lock);
113767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		ret = __blk_end_request(req, 0, brq->data.bytes_xfered);
113867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		spin_unlock_irq(&md->lock);
113967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	}
114067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	return ret;
114167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter}
114267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
1143ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlinstatic int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
114454d49d77628bed77e5491b8a2a1158a492843a19Per Forlin{
114554d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	struct mmc_blk_data *md = mq->data;
114654d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	struct mmc_card *card = md->queue.card;
114754d49d77628bed77e5491b8a2a1158a492843a19Per Forlin	struct mmc_blk_request *brq = &mq->mqrq_cur->brq;
114867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter	int ret = 1, disable_multi = 0, retry = 0, type;
1149d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin	enum mmc_blk_status status;
1150ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	struct mmc_queue_req *mq_rq;
1151ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	struct request *req;
1152ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	struct mmc_async_req *areq;
11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1154ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	if (!rqc && !mq->mqrq_prev->req)
1155ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		return 0;
115698ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman
1157ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	do {
1158ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		if (rqc) {
1159ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
1160ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			areq = &mq->mqrq_cur->mmc_active;
1161ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		} else
1162ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			areq = NULL;
1163ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		areq = mmc_start_req(card->host, areq, (int *) &status);
1164ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		if (!areq)
1165ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			return 0;
1166ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin
1167ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		mq_rq = container_of(areq, struct mmc_queue_req, mmc_active);
1168ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		brq = &mq_rq->brq;
1169ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		req = mq_rq->req;
117067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE;
1171ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		mmc_queue_bounce_post(mq_rq);
117298ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman
1173d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		switch (status) {
1174d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		case MMC_BLK_SUCCESS:
1175d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		case MMC_BLK_PARTIAL:
1176d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			/*
1177d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 * A block was successfully transferred.
1178d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 */
117967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			mmc_blk_reset_success(md, type);
1180d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			spin_lock_irq(&md->lock);
1181d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			ret = __blk_end_request(req, 0,
1182d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin						brq->data.bytes_xfered);
1183d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			spin_unlock_irq(&md->lock);
118467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			/*
118567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 * If the blk_end_request function returns non-zero even
118667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 * though all data has been transferred and no errors
118767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 * were returned by the host controller, it's a bug.
118867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 */
1189ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			if (status == MMC_BLK_SUCCESS && ret) {
1190a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S				pr_err("%s BUG rq_tot %d d_xfer %d\n",
1191ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin				       __func__, blk_rq_bytes(req),
1192ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin				       brq->data.bytes_xfered);
1193ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin				rqc = NULL;
1194ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin				goto cmd_abort;
1195ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			}
1196d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			break;
1197d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		case MMC_BLK_CMD_ERR:
119867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			ret = mmc_blk_cmd_err(md, card, brq, req, ret);
119967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			if (!mmc_blk_reset(md, card->host, type))
120067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				break;
120167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			goto cmd_abort;
1202d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		case MMC_BLK_RETRY:
1203d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			if (retry++ < 5)
1204a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux				break;
120567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			/* Fall through */
1206d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin		case MMC_BLK_ABORT:
120767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			if (!mmc_blk_reset(md, card->host, type))
120867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				break;
12094c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux			goto cmd_abort;
121067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		case MMC_BLK_DATA_ERR: {
121167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			int err;
121267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter
121367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			err = mmc_blk_reset(md, card->host, type);
121467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			if (!err)
121567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				break;
121667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			if (err == -ENODEV)
121767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				goto cmd_abort;
121867716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			/* Fall through */
121967716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		}
122067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter		case MMC_BLK_ECC_ERR:
122167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			if (brq->data.blocks > 1) {
122267716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				/* Redo read one sector at a time */
122367716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				pr_warning("%s: retrying using single block read\n",
122467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter					   req->rq_disk->disk_name);
122567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				disable_multi = 1;
122667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter				break;
122767716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			}
1228d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			/*
1229d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 * After an error, we redo I/O one sector at a
1230d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 * time, so we only reach here after trying to
1231d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 * read a single sector.
1232d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			 */
1233d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			spin_lock_irq(&md->lock);
1234d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			ret = __blk_end_request(req, -EIO,
1235d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin						brq->data.blksz);
1236d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			spin_unlock_irq(&md->lock);
1237ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			if (!ret)
1238ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin				goto start_new_req;
1239d78d4a8ad53f345dd3c0bb5f8d377baa523739f7Per Forlin			break;
12404c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux		}
12414c2b8f26eb8b54203e0e7834e0f7a11a7ae15ef1Russell King - ARM Linux
1242ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		if (ret) {
1243ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			/*
124467716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter			 * In case of a incomplete request
1245ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			 * prepare it again and resend.
1246ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			 */
1247ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			mmc_blk_rw_rq_prep(mq_rq, card, disable_multi, mq);
1248ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			mmc_start_req(card->host, &mq_rq->mmc_active, NULL);
1249ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		}
12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (ret);
12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1254a01f3ccf845067de32189f8a8e85d22c381f93b9Russell King - ARM Linux cmd_abort:
12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irq(&md->lock);
1256fd539832c7d3a242269374dbcae2cd54da150930Kiyoshi Ueda	while (ret)
1257fd539832c7d3a242269374dbcae2cd54da150930Kiyoshi Ueda		ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irq(&md->lock);
12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1260ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin start_new_req:
1261ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	if (rqc) {
1262ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
1263ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		mmc_start_req(card->host, &mq->mqrq_cur->mmc_active, NULL);
1264ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	}
1265ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin
12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1269bd788c9665fb7c543aac21317059375632343337Adrian Hunterstatic int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
1270bd788c9665fb7c543aac21317059375632343337Adrian Hunter{
12711a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin	int ret;
12721a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin	struct mmc_blk_data *md = mq->data;
12731a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin	struct mmc_card *card = md->queue.card;
12741a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin
1275ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	if (req && !mq->mqrq_prev->req)
1276ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		/* claim host only for the first request */
1277ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		mmc_claim_host(card->host);
1278ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin
1279371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	ret = mmc_blk_part_switch(card, md);
1280371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (ret) {
12810d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter		if (req) {
12820d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter			spin_lock_irq(&md->lock);
12830d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter			__blk_end_request_all(req, -EIO);
12840d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter			spin_unlock_irq(&md->lock);
12850d7d85ca6e5dc7bd426d1d5989a44e93e8c7a0d3Adrian Hunter		}
1286371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		ret = 0;
1287371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		goto out;
1288371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	}
12891a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin
1290ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	if (req && req->cmd_flags & REQ_DISCARD) {
1291ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		/* complete ongoing async transfer before issuing discard */
1292ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		if (card->host->areq)
1293ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin			mmc_blk_issue_rw_rq(mq, NULL);
12944980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		if (req->cmd_flags & REQ_SECURE)
12951a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin			ret = mmc_blk_issue_secdiscard_rq(mq, req);
12964980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		else
12971a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin			ret = mmc_blk_issue_discard_rq(mq, req);
1298ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	} else if (req && req->cmd_flags & REQ_FLUSH) {
1299393f9a08e2ee72e42379489a5781feaf9c406d5fJaehoon Chung		/* complete ongoing async transfer before issuing flush */
1300393f9a08e2ee72e42379489a5781feaf9c406d5fJaehoon Chung		if (card->host->areq)
1301393f9a08e2ee72e42379489a5781feaf9c406d5fJaehoon Chung			mmc_blk_issue_rw_rq(mq, NULL);
13021a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin		ret = mmc_blk_issue_flush(mq, req);
13034980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	} else {
13041a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin		ret = mmc_blk_issue_rw_rq(mq, req);
13054980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	}
13061a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin
1307371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinout:
1308ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin	if (!req)
1309ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		/* release host only when there are no more requests */
1310ee8a43a51c7681f19fe23b6b936e1d8094a8b7d1Per Forlin		mmc_release_host(card->host);
13111a258db6f396e26c2c00b19c0107a891895d4584Andrei Warkentin	return ret;
1312bd788c9665fb7c543aac21317059375632343337Adrian Hunter}
13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1314a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell Kingstatic inline int mmc_blk_readonly(struct mmc_card *card)
1315a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King{
1316a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	return mmc_card_readonly(card) ||
1317a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	       !(card->csd.cmdclass & CCC_BLOCK_WRITE);
1318a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King}
1319a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
1320371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
1321371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin					      struct device *parent,
1322371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin					      sector_t size,
1323371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin					      bool default_ro,
1324371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin					      const char *subname)
13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md;
13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int devidx, ret;
13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13295e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	devidx = find_first_zero_bit(dev_use, max_devices);
13305e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	if (devidx >= max_devices)
13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSPC);
13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__set_bit(devidx, dev_use);
13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1334dd00cc486ab1c17049a535413d1751ef3482141cYoann Padioleau	md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
1335a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	if (!md) {
1336a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		ret = -ENOMEM;
1337a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		goto out;
1338a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	}
13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1340a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	/*
1341f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	 * !subname implies we are creating main mmc_blk_data that will be
1342f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	 * associated with mmc_card with mmc_set_drvdata. Due to device
1343f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	 * partitions, devidx will not coincide with a per-physical card
1344f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	 * index anymore so we keep track of a name index.
1345f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	 */
1346f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	if (!subname) {
1347f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin		md->name_idx = find_first_zero_bit(name_use, max_devices);
1348f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin		__set_bit(md->name_idx, name_use);
1349f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	}
1350f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	else
1351f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin		md->name_idx = ((struct mmc_blk_data *)
1352f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin				dev_to_disk(parent)->private_data)->name_idx;
1353f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin
1354f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	/*
1355a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * Set the read-only status based on the supported commands
1356a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * and the write protect switch.
1357a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 */
1358a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->read_only = mmc_blk_readonly(card);
13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13605e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	md->disk = alloc_disk(perdev_minors);
1361a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	if (md->disk == NULL) {
1362a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		ret = -ENOMEM;
1363a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		goto err_kfree;
1364a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	}
13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1366a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	spin_lock_init(&md->lock);
1367371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	INIT_LIST_HEAD(&md->part);
1368a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->usage = 1;
13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1370d09408ade08a08a710a247fb52aa50101e73ebf7Adrian Hunter	ret = mmc_init_queue(&md->queue, card, &md->lock, subname);
1371a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	if (ret)
1372a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		goto err_putdisk;
13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1374a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->queue.issue_fn = mmc_blk_issue_rq;
1375a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->queue.data = md;
1376d2b18394259ef621fd2a6322aa9934198fd87a6aRussell King
1377fe6b4c8840c5e23fe9b8696450cee8f2e8cebffdPierre Ossman	md->disk->major	= MMC_BLOCK_MAJOR;
13785e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	md->disk->first_minor = devidx * perdev_minors;
1379a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->disk->fops = &mmc_bdops;
1380a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->disk->private_data = md;
1381a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->disk->queue = md->queue.queue;
1382371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	md->disk->driverfs_dev = parent;
1383371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	set_disk_ro(md->disk, md->read_only || default_ro);
1384a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
1385a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	/*
1386a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * As discussed on lkml, GENHD_FL_REMOVABLE should:
1387a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 *
1388a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * - be set for removable media with permanent block devices
1389a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * - be unset for removable block devices with permanent media
1390a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 *
1391a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * Since MMC block devices clearly fall under the second
1392a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * case, we do not set GENHD_FL_REMOVABLE.  Userspace
1393a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * should use the block device creation/destruction hotplug
1394a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * messages to tell when the card is present.
1395a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 */
1396a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
1397f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
1398f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin		 "mmcblk%d%s", md->name_idx, subname ? subname : "");
1399a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
1400e1defc4ff0cf57aca6c5e3ff99fa503f5943c1f1Martin K. Petersen	blk_queue_logical_block_size(md->queue.queue, 512);
1401371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	set_capacity(md->disk, size);
1402d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin
1403f0d89972b01798cf9d245dfa1cacfa0ee78a3593Andrei Warkentin	if (mmc_host_cmd23(card->host)) {
1404f0d89972b01798cf9d245dfa1cacfa0ee78a3593Andrei Warkentin		if (mmc_card_mmc(card) ||
1405f0d89972b01798cf9d245dfa1cacfa0ee78a3593Andrei Warkentin		    (mmc_card_sd(card) &&
1406f0d89972b01798cf9d245dfa1cacfa0ee78a3593Andrei Warkentin		     card->scr.cmds & SD_SCR_CMD23_SUPPORT))
1407f0d89972b01798cf9d245dfa1cacfa0ee78a3593Andrei Warkentin			md->flags |= MMC_BLK_CMD23;
1408f0d89972b01798cf9d245dfa1cacfa0ee78a3593Andrei Warkentin	}
1409d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin
1410d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	if (mmc_card_mmc(card) &&
1411d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	    md->flags & MMC_BLK_CMD23 &&
1412d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	    ((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) ||
1413d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	     card->ext_csd.rel_sectors)) {
1414d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin		md->flags |= MMC_BLK_REL_WR;
1415d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin		blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA);
1416d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	}
1417d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin
1418371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return md;
1419371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1420371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin err_putdisk:
1421371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	put_disk(md->disk);
1422371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin err_kfree:
1423371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	kfree(md);
1424371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin out:
1425371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return ERR_PTR(ret);
1426371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
1427371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1428371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
1429371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
1430371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	sector_t size;
1431371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *md;
1432a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
143385a18ad93ec66888d85758630019b10a84257f3cPierre Ossman	if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) {
143485a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		/*
143585a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 * The EXT_CSD sector count is in number or 512 byte
143685a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 * sectors.
143785a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 */
1438371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		size = card->ext_csd.sectors;
143985a18ad93ec66888d85758630019b10a84257f3cPierre Ossman	} else {
144085a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		/*
144185a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 * The CSD capacity field is in units of read_blkbits.
144285a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 * set_capacity takes units of 512 bytes.
144385a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 */
1444371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		size = card->csd.capacity << (card->csd.read_blkbits - 9);
144585a18ad93ec66888d85758630019b10a84257f3cPierre Ossman	}
1446371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1447371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL);
14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return md;
1449371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
1450a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
1451371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic int mmc_blk_alloc_part(struct mmc_card *card,
1452371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			      struct mmc_blk_data *md,
1453371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			      unsigned int part_type,
1454371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			      sector_t size,
1455371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			      bool default_ro,
1456371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			      const char *subname)
1457371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
1458371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	char cap_str[10];
1459371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *part_md;
1460371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1461371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro,
1462371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin				    subname);
1463371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (IS_ERR(part_md))
1464371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		return PTR_ERR(part_md);
1465371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	part_md->part_type = part_type;
1466371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	list_add(&part_md->part, &md->part);
1467371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1468371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	string_get_size((u64)get_capacity(part_md->disk) << 9, STRING_UNITS_2,
1469371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			cap_str, sizeof(cap_str));
1470a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S	pr_info("%s: %s %s partition %u %s\n",
1471371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	       part_md->disk->disk_name, mmc_card_id(card),
1472371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	       mmc_card_name(card), part_md->part_type, cap_str);
1473371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return 0;
1474371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
1475371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1476e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon/* MMC Physical partitions consist of two boot partitions and
1477e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon * up to four general purpose partitions.
1478e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon * For each partition enabled in EXT_CSD a block device will be allocatedi
1479e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon * to provide access to the partition.
1480e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon */
1481e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon
1482371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
1483371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
1484e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon	int idx, ret = 0;
1485371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1486371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (!mmc_card_mmc(card))
1487371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		return 0;
1488371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1489e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon	for (idx = 0; idx < card->nr_parts; idx++) {
1490e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon		if (card->part[idx].size) {
1491e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon			ret = mmc_blk_alloc_part(card, md,
1492e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon				card->part[idx].part_cfg,
1493e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon				card->part[idx].size >> 9,
1494e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon				card->part[idx].force_ro,
1495e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon				card->part[idx].name);
1496e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon			if (ret)
1497e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon				return ret;
1498e0c368d571d946ff40f068344b5c2df90c93dd2eNamjae Jeon		}
1499371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	}
1500371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1501371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return ret;
15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int err;
15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1509b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman	mmc_claim_host(card->host);
15100f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter	err = mmc_set_blocklen(card, 512);
1511b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman	mmc_release_host(card->host);
15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (err) {
1514a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S		pr_err("%s: unable to set block size to 512: %d\n",
15150f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter			md->disk->disk_name, err);
15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1522371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic void mmc_blk_remove_req(struct mmc_blk_data *md)
1523371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
1524371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (md) {
1525371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		if (md->disk->flags & GENHD_FL_UP) {
1526371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			device_remove_file(disk_to_dev(md->disk), &md->force_ro);
1527371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1528371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			/* Stop new requests from getting into the queue */
1529371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			del_gendisk(md->disk);
1530371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		}
1531371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1532371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		/* Then flush out any already in there */
1533371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		mmc_cleanup_queue(&md->queue);
1534371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		mmc_blk_put(md);
1535371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	}
1536371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
1537371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1538371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic void mmc_blk_remove_parts(struct mmc_card *card,
1539371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin				 struct mmc_blk_data *md)
1540371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
1541371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct list_head *pos, *q;
1542371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *part_md;
1543371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1544f06c9153f5ecd47dfed23f87b9d08e42ff0e4170Andrei Warkentin	__clear_bit(md->name_idx, name_use);
1545371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	list_for_each_safe(pos, q, &md->part) {
1546371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		part_md = list_entry(pos, struct mmc_blk_data, part);
1547371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		list_del(pos);
1548371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		mmc_blk_remove_req(part_md);
1549371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	}
1550371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
1551371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1552371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentinstatic int mmc_add_disk(struct mmc_blk_data *md)
1553371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin{
1554371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	int ret;
1555371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1556371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	add_disk(md->disk);
1557371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	md->force_ro.show = force_ro_show;
1558371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	md->force_ro.store = force_ro_store;
1559641c3187b9d53cfd4c23b0ce2ab18a13d5e775e5Rabin Vincent	sysfs_attr_init(&md->force_ro.attr);
1560371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	md->force_ro.attr.name = "force_ro";
1561371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	md->force_ro.attr.mode = S_IRUGO | S_IWUSR;
1562371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	ret = device_create_file(disk_to_dev(md->disk), &md->force_ro);
1563371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (ret)
1564371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		del_gendisk(md->disk);
1565371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1566371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	return ret;
1567371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin}
1568371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
15696f60c22252af05df94352240f30f9fc84090d88dAndrei Warkentinstatic const struct mmc_fixup blk_fixups[] =
15706f60c22252af05df94352240f30f9fc84090d88dAndrei Warkentin{
15716a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	MMC_FIXUP("SEM02G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
15726a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	MMC_FIXUP("SEM04G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
15736a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
15746a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
15756a7a6b45f454686a1549729bfbae31f0b3b595d6Andrei Warkentin	MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
1576d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin
1577d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	/*
1578d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	 * Some MMC cards experience performance degradation with CMD23
1579d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	 * instead of CMD12-bounded multiblock transfers. For now we'll
1580d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	 * black list what's bad...
1581d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	 * - Certain Toshiba cards.
1582d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	 *
1583d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	 * N.B. This doesn't affect SD cards.
1584d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	 */
1585d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	MMC_FIXUP("MMC08G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
1586d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin		  MMC_QUIRK_BLK_NO_CMD23),
1587d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	MMC_FIXUP("MMC16G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
1588d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin		  MMC_QUIRK_BLK_NO_CMD23),
1589d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin	MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
1590d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023Andrei Warkentin		  MMC_QUIRK_BLK_NO_CMD23),
15916f60c22252af05df94352240f30f9fc84090d88dAndrei Warkentin	END_FIXUP
15926f60c22252af05df94352240f30f9fc84090d88dAndrei Warkentin};
15936f60c22252af05df94352240f30f9fc84090d88dAndrei Warkentin
15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mmc_blk_probe(struct mmc_card *card)
15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1596371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *md, *part_md;
15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int err;
1598a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman	char cap_str[10];
1599a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman
1600912490db699d83cb3d03570b63df7448677a3f56Pierre Ossman	/*
1601912490db699d83cb3d03570b63df7448677a3f56Pierre Ossman	 * Check that the card supports the command class(es) we need.
1602912490db699d83cb3d03570b63df7448677a3f56Pierre Ossman	 */
1603912490db699d83cb3d03570b63df7448677a3f56Pierre Ossman	if (!(card->csd.cmdclass & CCC_BLOCK_READ))
16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENODEV;
16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	md = mmc_blk_alloc(card);
16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (IS_ERR(md))
16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return PTR_ERR(md);
16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	err = mmc_blk_set_blksize(md, card);
16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (err)
16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1614444122fd58fdc83c96877a92b3f6288cafddb08dYi Li	string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2,
1615a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman			cap_str, sizeof(cap_str));
1616a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S	pr_info("%s: %s %s %s %s\n",
16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
1618a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman		cap_str, md->read_only ? "(ro)" : "");
16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1620371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (mmc_blk_alloc_parts(card, md))
1621371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		goto out;
1622371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_set_drvdata(card, md);
16246f60c22252af05df94352240f30f9fc84090d88dAndrei Warkentin	mmc_fixup_device(card, blk_fixups);
16256f60c22252af05df94352240f30f9fc84090d88dAndrei Warkentin
1626371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	if (mmc_add_disk(md))
1627371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		goto out;
1628371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1629371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	list_for_each_entry(part_md, &md->part, part) {
1630371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		if (mmc_add_disk(part_md))
1631371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			goto out;
1632371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	}
16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out:
1636371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	mmc_blk_remove_parts(card, md);
1637371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	mmc_blk_remove_req(md);
16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return err;
16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mmc_blk_remove(struct mmc_card *card)
16421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md = mmc_get_drvdata(card);
16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1645371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	mmc_blk_remove_parts(card, md);
1646ddd6fa7e794e62af3ec3eb4ffdc78489885701f2Adrian Hunter	mmc_claim_host(card->host);
1647ddd6fa7e794e62af3ec3eb4ffdc78489885701f2Adrian Hunter	mmc_blk_part_switch(card, md);
1648ddd6fa7e794e62af3ec3eb4ffdc78489885701f2Adrian Hunter	mmc_release_host(card->host);
1649371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	mmc_blk_remove_req(md);
16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_set_drvdata(card, NULL);
16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PM
16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1656371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *part_md;
16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md = mmc_get_drvdata(card);
16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md) {
16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mmc_queue_suspend(&md->queue);
1661371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		list_for_each_entry(part_md, &md->part, part) {
1662371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			mmc_queue_suspend(&part_md->queue);
1663371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		}
16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mmc_blk_resume(struct mmc_card *card)
16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1670371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin	struct mmc_blk_data *part_md;
16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md = mmc_get_drvdata(card);
16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md) {
16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mmc_blk_set_blksize(md, card);
1675371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin
1676371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		/*
1677371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		 * Resume involves the card going into idle state,
1678371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		 * so current partition is always the main one.
1679371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		 */
1680371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		md->part_curr = md->part_type;
16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mmc_queue_resume(&md->queue);
1682371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		list_for_each_entry(part_md, &md->part, part) {
1683371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin			mmc_queue_resume(&part_md->queue);
1684371a689f64b0da140c3bcd3f55305ffa1c3a58efAndrei Warkentin		}
16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	mmc_blk_suspend	NULL
16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define mmc_blk_resume	NULL
16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mmc_driver mmc_driver = {
16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.drv		= {
16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.name	= "mmcblk",
16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.probe		= mmc_blk_probe,
16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.remove		= mmc_blk_remove,
16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.suspend	= mmc_blk_suspend,
17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.resume		= mmc_blk_resume,
17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init mmc_blk_init(void)
17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
17059d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	int res;
17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17075e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	if (perdev_minors != CONFIG_MMC_BLOCK_MINORS)
17085e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson		pr_info("mmcblk: using %d minors per device\n", perdev_minors);
17095e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
17105e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	max_devices = 256 / perdev_minors;
17115e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
1712fe6b4c8840c5e23fe9b8696450cee8f2e8cebffdPierre Ossman	res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
1713fe6b4c8840c5e23fe9b8696450cee8f2e8cebffdPierre Ossman	if (res)
17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17169d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	res = mmc_register_driver(&mmc_driver);
17179d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	if (res)
17189d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita		goto out2;
17191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17209d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	return 0;
17219d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita out2:
17229d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out:
17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return res;
17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit mmc_blk_exit(void)
17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_unregister_driver(&mmc_driver);
1730fe6b4c8840c5e23fe9b8696450cee8f2e8cebffdPierre Ossman	unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(mmc_blk_init);
17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(mmc_blk_exit);
17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("Multimedia Card (MMC) block device driver");
17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1739