aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r--drivers/mmc/card/block.c82
1 files changed, 45 insertions, 37 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c80bb6de40b8..ad0fb8d74dda 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -266,6 +266,9 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
266 goto idata_err; 266 goto idata_err;
267 } 267 }
268 268
269 if (!idata->buf_bytes)
270 return idata;
271
269 idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); 272 idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL);
270 if (!idata->buf) { 273 if (!idata->buf) {
271 err = -ENOMEM; 274 err = -ENOMEM;
@@ -312,25 +315,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
312 if (IS_ERR(idata)) 315 if (IS_ERR(idata))
313 return PTR_ERR(idata); 316 return PTR_ERR(idata);
314 317
315 cmd.opcode = idata->ic.opcode;
316 cmd.arg = idata->ic.arg;
317 cmd.flags = idata->ic.flags;
318
319 data.sg = &sg;
320 data.sg_len = 1;
321 data.blksz = idata->ic.blksz;
322 data.blocks = idata->ic.blocks;
323
324 sg_init_one(data.sg, idata->buf, idata->buf_bytes);
325
326 if (idata->ic.write_flag)
327 data.flags = MMC_DATA_WRITE;
328 else
329 data.flags = MMC_DATA_READ;
330
331 mrq.cmd = &cmd;
332 mrq.data = &data;
333
334 md = mmc_blk_get(bdev->bd_disk); 318 md = mmc_blk_get(bdev->bd_disk);
335 if (!md) { 319 if (!md) {
336 err = -EINVAL; 320 err = -EINVAL;
@@ -343,6 +327,48 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
343 goto cmd_done; 327 goto cmd_done;
344 } 328 }
345 329
330 cmd.opcode = idata->ic.opcode;
331 cmd.arg = idata->ic.arg;
332 cmd.flags = idata->ic.flags;
333
334 if (idata->buf_bytes) {
335 data.sg = &sg;
336 data.sg_len = 1;
337 data.blksz = idata->ic.blksz;
338 data.blocks = idata->ic.blocks;
339
340 sg_init_one(data.sg, idata->buf, idata->buf_bytes);
341
342 if (idata->ic.write_flag)
343 data.flags = MMC_DATA_WRITE;
344 else
345 data.flags = MMC_DATA_READ;
346
347 /* data.flags must already be set before doing this. */
348 mmc_set_data_timeout(&data, card);
349
350 /* Allow overriding the timeout_ns for empirical tuning. */
351 if (idata->ic.data_timeout_ns)
352 data.timeout_ns = idata->ic.data_timeout_ns;
353
354 if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
355 /*
356 * Pretend this is a data transfer and rely on the
357 * host driver to compute timeout. When all host
358 * drivers support cmd.cmd_timeout for R1B, this
359 * can be changed to:
360 *
361 * mrq.data = NULL;
362 * cmd.cmd_timeout = idata->ic.cmd_timeout_ms;
363 */
364 data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000;
365 }
366
367 mrq.data = &data;
368 }
369
370 mrq.cmd = &cmd;
371
346 mmc_claim_host(card->host); 372 mmc_claim_host(card->host);
347 373
348 if (idata->ic.is_acmd) { 374 if (idata->ic.is_acmd) {
@@ -351,24 +377,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
351 goto cmd_rel_host; 377 goto cmd_rel_host;
352 } 378 }
353 379
354 /* data.flags must already be set before doing this. */
355 mmc_set_data_timeout(&data, card);
356 /* Allow overriding the timeout_ns for empirical tuning. */
357 if (idata->ic.data_timeout_ns)
358 data.timeout_ns = idata->ic.data_timeout_ns;
359
360 if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
361 /*
362 * Pretend this is a data transfer and rely on the host driver
363 * to compute timeout. When all host drivers support
364 * cmd.cmd_timeout for R1B, this can be changed to:
365 *
366 * mrq.data = NULL;
367 * cmd.cmd_timeout = idata->ic.cmd_timeout_ms;
368 */
369 data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000;
370 }
371
372 mmc_wait_for_req(card->host, &mrq); 380 mmc_wait_for_req(card->host, &mrq);
373 381
374 if (cmd.error) { 382 if (cmd.error) {