block.c revision 5e71b7a64cb4c6cff75ca42b535d8227526ec592
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>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mmc/card.h>
36385e3227d4d83ab13d7767c4bb3593b0256bf246Pierre Ossman#include <linux/mmc/host.h>
37da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include <linux/mmc/mmc.h>
38da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include <linux/mmc/sd.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/system.h>
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4398ac2162699f7e9880683cb954891817f20b607cPierre Ossman#include "queue.h"
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
456b0b62853b2553be375033776902640320970846Andy WhitcroftMODULE_ALIAS("mmc:block");
465e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson#ifdef MODULE_PARAM_PREFIX
475e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson#undef MODULE_PARAM_PREFIX
485e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson#endif
495e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson#define MODULE_PARAM_PREFIX "mmcblk."
505e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
515e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonstatic DEFINE_MUTEX(block_mutex);
526b0b62853b2553be375033776902640320970846Andy Whitcroft
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
545e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson * The defaults come from config options but can be overriden by module
555e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson * or bootarg options.
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
575e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonstatic int perdev_minors = CONFIG_MMC_BLOCK_MINORS;
581dff314451fa24d6b107aa05393d3169e56a7e0aDavid Woodhouse
595e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson/*
605e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson * We've only got one major, so number of mmcblk devices is
615e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson * limited to 256 / number of minors per device.
625e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson */
635e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonstatic int max_devices;
645e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
655e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson/* 256 minors, so at most 256 separate devices */
665e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonstatic DECLARE_BITMAP(dev_use, 256);
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * There is one mmc_blk_data per slot.
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mmc_blk_data {
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spinlock_t	lock;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct gendisk	*disk;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_queue queue;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int	usage;
77a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	unsigned int	read_only;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
80a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Venstatic DEFINE_MUTEX(open_lock);
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
825e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johanssonmodule_param(perdev_minors, int, 0444);
835e71b7a64cb4c6cff75ca42b535d8227526ec592Olof JohanssonMODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
845e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md;
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
89a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven	mutex_lock(&open_lock);
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	md = disk->private_data;
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md && md->usage == 0)
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		md = NULL;
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md)
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		md->usage++;
95a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven	mutex_unlock(&open_lock);
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return md;
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mmc_blk_put(struct mmc_blk_data *md)
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
102a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven	mutex_lock(&open_lock);
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	md->usage--;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md->usage == 0) {
1057d92df692994472cab6045bbd9d0e2c4afa4365fAnna Lemehova		int devmaj = MAJOR(disk_devt(md->disk));
1065e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson		int devidx = MINOR(disk_devt(md->disk)) / perdev_minors;
1077d92df692994472cab6045bbd9d0e2c4afa4365fAnna Lemehova
1087d92df692994472cab6045bbd9d0e2c4afa4365fAnna Lemehova		if (!devmaj)
1095e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson			devidx = md->disk->first_minor / perdev_minors;
1107d92df692994472cab6045bbd9d0e2c4afa4365fAnna Lemehova
1115fa83ce284a4b7cd9dcfadd01500b0ed4ab9b740Adrian Hunter		blk_cleanup_queue(md->queue.queue);
1125fa83ce284a4b7cd9dcfadd01500b0ed4ab9b740Adrian Hunter
1131dff314451fa24d6b107aa05393d3169e56a7e0aDavid Woodhouse		__clear_bit(devidx, dev_use);
1141dff314451fa24d6b107aa05393d3169e56a7e0aDavid Woodhouse
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_disk(md->disk);
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(md);
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
118a621aaed690b9439141c555941b6af53873f6ff1Arjan van de Ven	mutex_unlock(&open_lock);
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
121a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Virostatic int mmc_blk_open(struct block_device *bdev, fmode_t mode)
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
123a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro	struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret = -ENXIO;
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1262a48fc0ab24241755dc93bfd4f01d68efab47f5aArnd Bergmann	mutex_lock(&block_mutex);
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md) {
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (md->usage == 2)
129a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro			check_disk_change(bdev);
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = 0;
131a00fc09029f02ca833cf90e5d5625f08c4ac4f51Pierre Ossman
132a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro		if ((mode & FMODE_WRITE) && md->read_only) {
13370bb08962ea9bd50797ae9f16b2493f5f7c65053Andrew Morton			mmc_blk_put(md);
134a00fc09029f02ca833cf90e5d5625f08c4ac4f51Pierre Ossman			ret = -EROFS;
13570bb08962ea9bd50797ae9f16b2493f5f7c65053Andrew Morton		}
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1372a48fc0ab24241755dc93bfd4f01d68efab47f5aArnd Bergmann	mutex_unlock(&block_mutex);
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
142a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Virostatic int mmc_blk_release(struct gendisk *disk, fmode_t mode)
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
144a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro	struct mmc_blk_data *md = disk->private_data;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1462a48fc0ab24241755dc93bfd4f01d68efab47f5aArnd Bergmann	mutex_lock(&block_mutex);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_blk_put(md);
1482a48fc0ab24241755dc93bfd4f01d68efab47f5aArnd Bergmann	mutex_unlock(&block_mutex);
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
153a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwigmmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
155a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
156a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	geo->heads = 4;
157a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	geo->sectors = 16;
158a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	return 0;
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16183d5cde47dedf01b6a4a4331882cbc0a7eea3c2eAlexey Dobriyanstatic const struct block_device_operations mmc_bdops = {
162a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro	.open			= mmc_blk_open,
163a5a1561f88fe8bfd7fdceed1d942ad494500b8a9Al Viro	.release		= mmc_blk_release,
164a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig	.getgeo			= mmc_blk_getgeo,
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.owner			= THIS_MODULE,
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mmc_blk_request {
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_request	mrq;
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_command	cmd;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_command	stop;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_data		data;
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
175ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossmanstatic u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
176ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman{
177ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	int err;
178051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	u32 result;
179051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	__be32 *blocks;
180ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
181ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	struct mmc_request mrq;
182ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	struct mmc_command cmd;
183ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	struct mmc_data data;
184ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	unsigned int timeout_us;
185ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
186ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	struct scatterlist sg;
187ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
188ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	memset(&cmd, 0, sizeof(struct mmc_command));
189ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
190ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	cmd.opcode = MMC_APP_CMD;
191ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	cmd.arg = card->rca << 16;
1927213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
193ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
194ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	err = mmc_wait_for_cmd(card->host, &cmd, 0);
1957213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell	if (err)
1967213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell		return (u32)-1;
1977213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell	if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
198ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		return (u32)-1;
199ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
200ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	memset(&cmd, 0, sizeof(struct mmc_command));
201ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
202ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	cmd.opcode = SD_APP_SEND_NUM_WR_BLKS;
203ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	cmd.arg = 0;
2047213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
205ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
206ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	memset(&data, 0, sizeof(struct mmc_data));
207ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
208ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.timeout_ns = card->csd.tacc_ns * 100;
209ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.timeout_clks = card->csd.tacc_clks * 100;
210ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
211ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	timeout_us = data.timeout_ns / 1000;
212ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	timeout_us += data.timeout_clks * 1000 /
213ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		(card->host->ios.clock / 1000);
214ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
215ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	if (timeout_us > 100000) {
216ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		data.timeout_ns = 100000000;
217ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		data.timeout_clks = 0;
218ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	}
219ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
220ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.blksz = 4;
221ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.blocks = 1;
222ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.flags = MMC_DATA_READ;
223ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.sg = &sg;
224ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	data.sg_len = 1;
225ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
226ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	memset(&mrq, 0, sizeof(struct mmc_request));
227ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
228ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	mrq.cmd = &cmd;
229ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	mrq.data = &data;
230ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
231051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	blocks = kmalloc(4, GFP_KERNEL);
232051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	if (!blocks)
233051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks		return (u32)-1;
234051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks
235051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	sg_init_one(&sg, blocks, 4);
236ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
237ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	mmc_wait_for_req(card->host, &mrq);
238ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
239051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	result = ntohl(*blocks);
240051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	kfree(blocks);
241051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks
24217b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman	if (cmd.error || data.error)
243051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks		result = (u32)-1;
244ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
245051913dada046ac948eb6f48c0717fc25de2a917Ben Dooks	return result;
246ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman}
247ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
248504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunterstatic u32 get_card_status(struct mmc_card *card, struct request *req)
249504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter{
250504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	struct mmc_command cmd;
251504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	int err;
252504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter
253504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	memset(&cmd, 0, sizeof(struct mmc_command));
254504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	cmd.opcode = MMC_SEND_STATUS;
255504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	if (!mmc_host_is_spi(card->host))
256504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter		cmd.arg = card->rca << 16;
257504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
258504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	err = mmc_wait_for_cmd(card->host, &cmd, 0);
259504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	if (err)
260504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter		printk(KERN_ERR "%s: error %d sending status comand",
261504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter		       req->rq_disk->disk_name, err);
262504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter	return cmd.resp[0];
263504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter}
264504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter
265bd788c9665fb7c543aac21317059375632343337Adrian Hunterstatic int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
266bd788c9665fb7c543aac21317059375632343337Adrian Hunter{
267bd788c9665fb7c543aac21317059375632343337Adrian Hunter	struct mmc_blk_data *md = mq->data;
268bd788c9665fb7c543aac21317059375632343337Adrian Hunter	struct mmc_card *card = md->queue.card;
269bd788c9665fb7c543aac21317059375632343337Adrian Hunter	unsigned int from, nr, arg;
270bd788c9665fb7c543aac21317059375632343337Adrian Hunter	int err = 0;
271bd788c9665fb7c543aac21317059375632343337Adrian Hunter
272bd788c9665fb7c543aac21317059375632343337Adrian Hunter	mmc_claim_host(card->host);
273bd788c9665fb7c543aac21317059375632343337Adrian Hunter
274bd788c9665fb7c543aac21317059375632343337Adrian Hunter	if (!mmc_can_erase(card)) {
275bd788c9665fb7c543aac21317059375632343337Adrian Hunter		err = -EOPNOTSUPP;
276bd788c9665fb7c543aac21317059375632343337Adrian Hunter		goto out;
277bd788c9665fb7c543aac21317059375632343337Adrian Hunter	}
278bd788c9665fb7c543aac21317059375632343337Adrian Hunter
279bd788c9665fb7c543aac21317059375632343337Adrian Hunter	from = blk_rq_pos(req);
280bd788c9665fb7c543aac21317059375632343337Adrian Hunter	nr = blk_rq_sectors(req);
281bd788c9665fb7c543aac21317059375632343337Adrian Hunter
282bd788c9665fb7c543aac21317059375632343337Adrian Hunter	if (mmc_can_trim(card))
283bd788c9665fb7c543aac21317059375632343337Adrian Hunter		arg = MMC_TRIM_ARG;
284bd788c9665fb7c543aac21317059375632343337Adrian Hunter	else
285bd788c9665fb7c543aac21317059375632343337Adrian Hunter		arg = MMC_ERASE_ARG;
286bd788c9665fb7c543aac21317059375632343337Adrian Hunter
287bd788c9665fb7c543aac21317059375632343337Adrian Hunter	err = mmc_erase(card, from, nr, arg);
288bd788c9665fb7c543aac21317059375632343337Adrian Hunterout:
289bd788c9665fb7c543aac21317059375632343337Adrian Hunter	spin_lock_irq(&md->lock);
290bd788c9665fb7c543aac21317059375632343337Adrian Hunter	__blk_end_request(req, err, blk_rq_bytes(req));
291bd788c9665fb7c543aac21317059375632343337Adrian Hunter	spin_unlock_irq(&md->lock);
292bd788c9665fb7c543aac21317059375632343337Adrian Hunter
293bd788c9665fb7c543aac21317059375632343337Adrian Hunter	mmc_release_host(card->host);
294bd788c9665fb7c543aac21317059375632343337Adrian Hunter
295bd788c9665fb7c543aac21317059375632343337Adrian Hunter	return err ? 0 : 1;
296bd788c9665fb7c543aac21317059375632343337Adrian Hunter}
297bd788c9665fb7c543aac21317059375632343337Adrian Hunter
2984980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunterstatic int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
2994980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter				       struct request *req)
3004980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter{
3014980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	struct mmc_blk_data *md = mq->data;
3024980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	struct mmc_card *card = md->queue.card;
3034980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	unsigned int from, nr, arg;
3044980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	int err = 0;
3054980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
3064980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	mmc_claim_host(card->host);
3074980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
3084980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	if (!mmc_can_secure_erase_trim(card)) {
3094980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		err = -EOPNOTSUPP;
3104980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		goto out;
3114980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	}
3124980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
3134980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	from = blk_rq_pos(req);
3144980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	nr = blk_rq_sectors(req);
3154980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
3164980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
3174980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		arg = MMC_SECURE_TRIM1_ARG;
3184980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	else
3194980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		arg = MMC_SECURE_ERASE_ARG;
3204980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
3214980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	err = mmc_erase(card, from, nr, arg);
3224980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	if (!err && arg == MMC_SECURE_TRIM1_ARG)
3234980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
3244980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunterout:
3254980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	spin_lock_irq(&md->lock);
3264980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	__blk_end_request(req, err, blk_rq_bytes(req));
3274980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	spin_unlock_irq(&md->lock);
3284980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
3294980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	mmc_release_host(card->host);
3304980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
3314980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	return err ? 0 : 1;
3324980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter}
3334980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter
334bd788c9665fb7c543aac21317059375632343337Adrian Hunterstatic int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md = mq->data;
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_card *card = md->queue.card;
338176f00ffed3ef94a198326fbf6a5db64f1cf73adPierre Ossman	struct mmc_blk_request brq;
3396a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter	int ret = 1, disable_multi = 0;
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman	mmc_claim_host(card->host);
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct mmc_command cmd;
345504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter		u32 readcmd, writecmd, status = 0;
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset(&brq, 0, sizeof(struct mmc_blk_request));
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		brq.mrq.cmd = &brq.cmd;
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		brq.mrq.data = &brq.data;
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
35183096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo		brq.cmd.arg = blk_rq_pos(req);
352fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale		if (!mmc_card_blockaddr(card))
353fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale			brq.cmd.arg <<= 9;
3547213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell		brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
35508846698703dedae6c6915eb4b4d0a36188c5635Pierre Ossman		brq.data.blksz = 512;
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		brq.stop.opcode = MMC_STOP_TRANSMISSION;
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		brq.stop.arg = 0;
3587213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell		brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
35983096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo		brq.data.blocks = blk_rq_sectors(req);
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3616a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		/*
362548d2de9bd978a4d4e941477500f1ab97aade137Pierre Ossman		 * The block layer doesn't support all sector count
363548d2de9bd978a4d4e941477500f1ab97aade137Pierre Ossman		 * restrictions, so we need to be prepared for too big
364548d2de9bd978a4d4e941477500f1ab97aade137Pierre Ossman		 * requests.
365548d2de9bd978a4d4e941477500f1ab97aade137Pierre Ossman		 */
366548d2de9bd978a4d4e941477500f1ab97aade137Pierre Ossman		if (brq.data.blocks > card->host->max_blk_count)
367548d2de9bd978a4d4e941477500f1ab97aade137Pierre Ossman			brq.data.blocks = card->host->max_blk_count;
368548d2de9bd978a4d4e941477500f1ab97aade137Pierre Ossman
369548d2de9bd978a4d4e941477500f1ab97aade137Pierre Ossman		/*
3706a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		 * After a read error, we redo the request one sector at a time
3716a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		 * in order to accurately determine which sectors can be read
3726a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		 * successfully.
3736a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		 */
3746a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		if (disable_multi && brq.data.blocks > 1)
3756a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			brq.data.blocks = 1;
3766a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter
377788ee7b09883515f3a72a8f2a980df5e94f37e2cRussell King		if (brq.data.blocks > 1) {
3787213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell			/* SPI multiblock writes terminate using a special
3797213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell			 * token, not a STOP_TRANSMISSION request.
3807213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell			 */
3817213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell			if (!mmc_host_is_spi(card->host)
3827213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell					|| rq_data_dir(req) == READ)
3837213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell				brq.mrq.stop = &brq.stop;
384db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King			readcmd = MMC_READ_MULTIPLE_BLOCK;
385db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King			writecmd = MMC_WRITE_MULTIPLE_BLOCK;
386788ee7b09883515f3a72a8f2a980df5e94f37e2cRussell King		} else {
387788ee7b09883515f3a72a8f2a980df5e94f37e2cRussell King			brq.mrq.stop = NULL;
388db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King			readcmd = MMC_READ_SINGLE_BLOCK;
389db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King			writecmd = MMC_WRITE_BLOCK;
390db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King		}
391db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King		if (rq_data_dir(req) == READ) {
392db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King			brq.cmd.opcode = readcmd;
393db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King			brq.data.flags |= MMC_DATA_READ;
394db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King		} else {
395db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King			brq.cmd.opcode = writecmd;
396db53f28b3a6d9338cca1b7e917dc063ac99e1871Russell King			brq.data.flags |= MMC_DATA_WRITE;
397788ee7b09883515f3a72a8f2a980df5e94f37e2cRussell King		}
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
399b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossman		mmc_set_data_timeout(&brq.data, card);
400b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossman
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		brq.data.sg = mq->sg;
40298ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman		brq.data.sg_len = mmc_queue_map_sg(mq);
40398ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman
4046a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		/*
4056a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		 * Adjust the sg list so it is the same size as the
4066a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		 * request.
4076a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		 */
40883096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo		if (brq.data.blocks != blk_rq_sectors(req)) {
4096a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			int i, data_size = brq.data.blocks << 9;
4106a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			struct scatterlist *sg;
4116a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter
4126a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) {
4136a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				data_size -= sg->length;
4146a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				if (data_size <= 0) {
4156a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter					sg->length += data_size;
4166a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter					i++;
4176a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter					break;
4186a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				}
4196a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			}
4206a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			brq.data.sg_len = i;
4216a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		}
4226a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter
42398ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman		mmc_queue_bounce_pre(mq);
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mmc_wait_for_req(card->host, &brq.mrq);
42698ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman
42798ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman		mmc_queue_bounce_post(mq);
42898ccf14909ba02a41c5925b0b2c92aeeef23d3b9Pierre Ossman
429979ce7208a679b8d012450610d5d5aa75aab3af9Pierre Ossman		/*
430979ce7208a679b8d012450610d5d5aa75aab3af9Pierre Ossman		 * Check for errors here, but don't jump to cmd_err
431979ce7208a679b8d012450610d5d5aa75aab3af9Pierre Ossman		 * until later as we need to wait for the card to leave
432979ce7208a679b8d012450610d5d5aa75aab3af9Pierre Ossman		 * programming mode even when things go wrong.
433979ce7208a679b8d012450610d5d5aa75aab3af9Pierre Ossman		 */
4346a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		if (brq.cmd.error || brq.data.error || brq.stop.error) {
4356a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			if (brq.data.blocks > 1 && rq_data_dir(req) == READ) {
4366a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				/* Redo read one sector at a time */
4376a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				printk(KERN_WARNING "%s: retrying using single "
4386a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				       "block read\n", req->rq_disk->disk_name);
4396a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				disable_multi = 1;
4406a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				continue;
4416a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			}
442504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			status = get_card_status(card, req);
4436a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		}
444504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (brq.cmd.error) {
446504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			printk(KERN_ERR "%s: error %d sending read/write "
447504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			       "command, response %#x, card status %#x\n",
448504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			       req->rq_disk->disk_name, brq.cmd.error,
449504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			       brq.cmd.resp[0], status);
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (brq.data.error) {
453504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			if (brq.data.error == -ETIMEDOUT && brq.mrq.stop)
454504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter				/* 'Stop' response contains card status */
455504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter				status = brq.mrq.stop->resp[0];
456504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			printk(KERN_ERR "%s: error %d transferring data,"
457504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			       " sector %u, nr %u, card status %#x\n",
458504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			       req->rq_disk->disk_name, brq.data.error,
45983096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo			       (unsigned)blk_rq_pos(req),
46083096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo			       (unsigned)blk_rq_sectors(req), status);
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (brq.stop.error) {
464504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			printk(KERN_ERR "%s: error %d sending stop command, "
465504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			       "response %#x, card status %#x\n",
466504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			       req->rq_disk->disk_name, brq.stop.error,
467504f191f25b1671802246bac06c9f59f94f0b7deAdrian Hunter			       brq.stop.resp[0], status);
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4707213d175e3b6f6db60f843b72e88857a350e146aDavid Brownell		if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
4712ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King			do {
4722ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				int err;
4732ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King
4742ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				cmd.opcode = MMC_SEND_STATUS;
4752ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				cmd.arg = card->rca << 16;
4762ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
4772ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				err = mmc_wait_for_cmd(card->host, &cmd, 5);
4782ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				if (err) {
4792ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King					printk(KERN_ERR "%s: error %d requesting status\n",
4802ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King					       req->rq_disk->disk_name, err);
4812ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King					goto cmd_err;
4822ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				}
483d198f101989d9bb950327f0d043f6203bb862343Pierre Ossman				/*
484d198f101989d9bb950327f0d043f6203bb862343Pierre Ossman				 * Some cards mishandle the status bits,
485d198f101989d9bb950327f0d043f6203bb862343Pierre Ossman				 * so make sure to check both the busy
486d198f101989d9bb950327f0d043f6203bb862343Pierre Ossman				 * indication and the card state.
487d198f101989d9bb950327f0d043f6203bb862343Pierre Ossman				 */
488d198f101989d9bb950327f0d043f6203bb862343Pierre Ossman			} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
489d198f101989d9bb950327f0d043f6203bb862343Pierre Ossman				(R1_CURRENT_STATE(cmd.resp[0]) == 7));
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0
4922ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King			if (cmd.resp[0] & ~0x00000900)
4932ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				printk(KERN_ERR "%s: status = %08x\n",
4942ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				       req->rq_disk->disk_name, cmd.resp[0]);
4952ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King			if (mmc_decode_status(cmd.resp))
4962ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King				goto cmd_err;
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
4982ed6d22cec37d9a3df4c5bacf1160dee7700106eRussell King		}
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5006a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		if (brq.cmd.error || brq.stop.error || brq.data.error) {
5016a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			if (rq_data_dir(req) == READ) {
5026a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				/*
5036a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				 * After an error, we redo I/O one sector at a
5046a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				 * time, so we only reach here after trying to
5056a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				 * read a single sector.
5066a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				 */
5076a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				spin_lock_irq(&md->lock);
5086a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				ret = __blk_end_request(req, -EIO, brq.data.blksz);
5096a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				spin_unlock_irq(&md->lock);
5106a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter				continue;
5116a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			}
512979ce7208a679b8d012450610d5d5aa75aab3af9Pierre Ossman			goto cmd_err;
5136a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		}
514979ce7208a679b8d012450610d5d5aa75aab3af9Pierre Ossman
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * A block was successfully transferred.
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_lock_irq(&md->lock);
519fd539832c7d3a242269374dbcae2cd54da150930Kiyoshi Ueda		ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irq(&md->lock);
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (ret);
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
523b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman	mmc_release_host(card->host);
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd_err:
528ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman 	/*
529ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman 	 * If this is an SD card and we're writing, we can first
530ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman 	 * mark the known good sectors as ok.
531ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman 	 *
532ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman	 * If the card is not SD, we can still ok written sectors
53323af60398af2f5033e2f53665538a09f498dbc03Pierre Ossman	 * as reported by the controller (which might be less than
53423af60398af2f5033e2f53665538a09f498dbc03Pierre Ossman	 * the real number of written sectors, but never more).
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
5366a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter	if (mmc_card_sd(card)) {
5376a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		u32 blocks;
53823af60398af2f5033e2f53665538a09f498dbc03Pierre Ossman
5396a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		blocks = mmc_sd_num_wr_blocks(card);
5406a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		if (blocks != (u32)-1) {
541ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman			spin_lock_irq(&md->lock);
5426a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter			ret = __blk_end_request(req, 0, blocks << 9);
543ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman			spin_unlock_irq(&md->lock);
544ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman		}
5456a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter	} else {
5466a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		spin_lock_irq(&md->lock);
5476a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
5486a79e391df295bd7c2aa1309ea5031f361c197fdAdrian Hunter		spin_unlock_irq(&md->lock);
549176f00ffed3ef94a198326fbf6a5db64f1cf73adPierre Ossman	}
550176f00ffed3ef94a198326fbf6a5db64f1cf73adPierre Ossman
551b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman	mmc_release_host(card->host);
552ec5a19dd935eb3793e1f6ed491e8035b3d7b1df9Pierre Ossman
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irq(&md->lock);
554fd539832c7d3a242269374dbcae2cd54da150930Kiyoshi Ueda	while (ret)
555fd539832c7d3a242269374dbcae2cd54da150930Kiyoshi Ueda		ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irq(&md->lock);
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561bd788c9665fb7c543aac21317059375632343337Adrian Hunterstatic int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
562bd788c9665fb7c543aac21317059375632343337Adrian Hunter{
5634980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	if (req->cmd_flags & REQ_DISCARD) {
5644980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		if (req->cmd_flags & REQ_SECURE)
5654980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter			return mmc_blk_issue_secdiscard_rq(mq, req);
5664980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter		else
5674980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter			return mmc_blk_issue_discard_rq(mq, req);
5684980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	} else {
569bd788c9665fb7c543aac21317059375632343337Adrian Hunter		return mmc_blk_issue_rw_rq(mq, req);
5704980454868af4b2f84f1f15f4b76512eecb37e1dAdrian Hunter	}
571bd788c9665fb7c543aac21317059375632343337Adrian Hunter}
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
573a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell Kingstatic inline int mmc_blk_readonly(struct mmc_card *card)
574a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King{
575a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	return mmc_card_readonly(card) ||
576a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	       !(card->csd.cmdclass & CCC_BLOCK_WRITE);
577a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King}
578a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md;
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int devidx, ret;
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5845e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	devidx = find_first_zero_bit(dev_use, max_devices);
5855e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	if (devidx >= max_devices)
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSPC);
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__set_bit(devidx, dev_use);
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
589dd00cc486ab1c17049a535413d1751ef3482141cYoann Padioleau	md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
590a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	if (!md) {
591a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		ret = -ENOMEM;
592a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		goto out;
593a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	}
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
596a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	/*
597a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * Set the read-only status based on the supported commands
598a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * and the write protect switch.
599a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 */
600a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->read_only = mmc_blk_readonly(card);
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6025e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	md->disk = alloc_disk(perdev_minors);
603a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	if (md->disk == NULL) {
604a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		ret = -ENOMEM;
605a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		goto err_kfree;
606a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	}
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
608a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	spin_lock_init(&md->lock);
609a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->usage = 1;
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
611a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	ret = mmc_init_queue(&md->queue, card, &md->lock);
612a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	if (ret)
613a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King		goto err_putdisk;
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
615a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->queue.issue_fn = mmc_blk_issue_rq;
616a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->queue.data = md;
617d2b18394259ef621fd2a6322aa9934198fd87a6aRussell King
618fe6b4c8840c5e23fe9b8696450cee8f2e8cebffdPierre Ossman	md->disk->major	= MMC_BLOCK_MAJOR;
6195e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	md->disk->first_minor = devidx * perdev_minors;
620a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->disk->fops = &mmc_bdops;
621a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->disk->private_data = md;
622a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->disk->queue = md->queue.queue;
623a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	md->disk->driverfs_dev = &card->dev;
624a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
625a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	/*
626a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * As discussed on lkml, GENHD_FL_REMOVABLE should:
627a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 *
628a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * - be set for removable media with permanent block devices
629a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * - be unset for removable block devices with permanent media
630a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 *
631a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * Since MMC block devices clearly fall under the second
632a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * case, we do not set GENHD_FL_REMOVABLE.  Userspace
633a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * should use the block device creation/destruction hotplug
634a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 * messages to tell when the card is present.
635a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	 */
636a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
63712578f66b9058e63f193fbfe1552e1d1bfa361bbJiebingLi	snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
63812578f66b9058e63f193fbfe1552e1d1bfa361bbJiebingLi		"mmcblk%d", devidx);
639a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
640e1defc4ff0cf57aca6c5e3ff99fa503f5943c1f1Martin K. Petersen	blk_queue_logical_block_size(md->queue.queue, 512);
641a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
64285a18ad93ec66888d85758630019b10a84257f3cPierre Ossman	if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) {
64385a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		/*
64485a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 * The EXT_CSD sector count is in number or 512 byte
64585a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 * sectors.
64685a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 */
64785a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		set_capacity(md->disk, card->ext_csd.sectors);
64885a18ad93ec66888d85758630019b10a84257f3cPierre Ossman	} else {
64985a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		/*
65085a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 * The CSD capacity field is in units of read_blkbits.
65185a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 * set_capacity takes units of 512 bytes.
65285a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		 */
65385a18ad93ec66888d85758630019b10a84257f3cPierre Ossman		set_capacity(md->disk,
65485a18ad93ec66888d85758630019b10a84257f3cPierre Ossman			card->csd.capacity << (card->csd.read_blkbits - 9));
65585a18ad93ec66888d85758630019b10a84257f3cPierre Ossman	}
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return md;
657a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King
658a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King err_putdisk:
659a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	put_disk(md->disk);
660a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King err_kfree:
661a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	kfree(md);
662a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King out:
663a6f6c96b65d7f65a7a7bf5cbe874eda182a6b2ccRussell King	return ERR_PTR(ret);
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int err;
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman	mmc_claim_host(card->host);
6720f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter	err = mmc_set_blocklen(card, 512);
673b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman	mmc_release_host(card->host);
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (err) {
6760f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter		printk(KERN_ERR "%s: unable to set block size to 512: %d\n",
6770f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter			md->disk->disk_name, err);
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mmc_blk_probe(struct mmc_card *card)
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md;
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int err;
688a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman	char cap_str[10];
689a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman
690912490db699d83cb3d03570b63df7448677a3f56Pierre Ossman	/*
691912490db699d83cb3d03570b63df7448677a3f56Pierre Ossman	 * Check that the card supports the command class(es) we need.
692912490db699d83cb3d03570b63df7448677a3f56Pierre Ossman	 */
693912490db699d83cb3d03570b63df7448677a3f56Pierre Ossman	if (!(card->csd.cmdclass & CCC_BLOCK_READ))
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENODEV;
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	md = mmc_blk_alloc(card);
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (IS_ERR(md))
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return PTR_ERR(md);
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	err = mmc_blk_set_blksize(md, card);
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (err)
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
704444122fd58fdc83c96877a92b3f6288cafddb08dYi Li	string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2,
705a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman			cap_str, sizeof(cap_str));
706a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman	printk(KERN_INFO "%s: %s %s %s %s\n",
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
708a7bbb57333447d0cf950992653b6b079585f3531Pierre Ossman		cap_str, md->read_only ? "(ro)" : "");
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_set_drvdata(card, md);
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	add_disk(md->disk);
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out:
7150a74ff29b8dd8b748f8856352f9a9b5c6cc362ccJarkko Lavinen	mmc_cleanup_queue(&md->queue);
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_blk_put(md);
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return err;
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mmc_blk_remove(struct mmc_card *card)
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md = mmc_get_drvdata(card);
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md) {
72689b4e133afea9fce333054b94d89953583a55c19Pierre Ossman		/* Stop new requests from getting into the queue */
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		del_gendisk(md->disk);
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
72989b4e133afea9fce333054b94d89953583a55c19Pierre Ossman		/* Then flush out any already in there */
73089b4e133afea9fce333054b94d89953583a55c19Pierre Ossman		mmc_cleanup_queue(&md->queue);
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mmc_blk_put(md);
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_set_drvdata(card, NULL);
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PM
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md = mmc_get_drvdata(card);
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md) {
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mmc_queue_suspend(&md->queue);
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mmc_blk_resume(struct mmc_card *card)
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mmc_blk_data *md = mmc_get_drvdata(card);
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (md) {
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mmc_blk_set_blksize(md, card);
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mmc_queue_resume(&md->queue);
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	mmc_blk_suspend	NULL
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define mmc_blk_resume	NULL
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mmc_driver mmc_driver = {
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.drv		= {
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.name	= "mmcblk",
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.probe		= mmc_blk_probe,
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.remove		= mmc_blk_remove,
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.suspend	= mmc_blk_suspend,
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.resume		= mmc_blk_resume,
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init mmc_blk_init(void)
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7759d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	int res;
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7775e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	if (perdev_minors != CONFIG_MMC_BLOCK_MINORS)
7785e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson		pr_info("mmcblk: using %d minors per device\n", perdev_minors);
7795e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
7805e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson	max_devices = 256 / perdev_minors;
7815e71b7a64cb4c6cff75ca42b535d8227526ec592Olof Johansson
782fe6b4c8840c5e23fe9b8696450cee8f2e8cebffdPierre Ossman	res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
783fe6b4c8840c5e23fe9b8696450cee8f2e8cebffdPierre Ossman	if (res)
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7869d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	res = mmc_register_driver(&mmc_driver);
7879d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	if (res)
7889d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita		goto out2;
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7909d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	return 0;
7919d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita out2:
7929d4e98e9609bc19d4a8ac4a5c3218358d1820114Akinobu Mita	unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out:
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return res;
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit mmc_blk_exit(void)
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmc_unregister_driver(&mmc_driver);
800fe6b4c8840c5e23fe9b8696450cee8f2e8cebffdPierre Ossman	unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(mmc_blk_init);
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(mmc_blk_exit);
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("Multimedia Card (MMC) block device driver");
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
809