diff options
Diffstat (limited to 'drivers/mmc/core/block.c')
| -rw-r--r-- | drivers/mmc/core/block.c | 67 | 
1 files changed, 59 insertions, 8 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index ea80ff4cd7f9..ccfa98af1dd3 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -122,6 +122,10 @@ struct mmc_blk_data {  	struct device_attribute force_ro;  	struct device_attribute power_ro_lock;  	int	area_type; + +	/* debugfs files (only in main mmc_blk_data) */ +	struct dentry *status_dentry; +	struct dentry *ext_csd_dentry;  };  /* Device type for RPMB character devices */ @@ -233,9 +237,14 @@ static ssize_t power_ro_lock_store(struct device *dev,  	/* Dispatch locking to the block layer */  	req = blk_get_request(mq->queue, REQ_OP_DRV_OUT, __GFP_RECLAIM); +	if (IS_ERR(req)) { +		count = PTR_ERR(req); +		goto out_put; +	}  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_BOOT_WP;  	blk_execute_rq(mq->queue, NULL, req, 0);  	ret = req_to_mmc_queue_req(req)->drv_op_result; +	blk_put_request(req);  	if (!ret) {  		pr_info("%s: Locking boot partition ro until next power on\n", @@ -248,7 +257,7 @@ static ssize_t power_ro_lock_store(struct device *dev,  				set_disk_ro(part_md->disk, 1);  			}  	} - +out_put:  	mmc_blk_put(md);  	return count;  } @@ -624,6 +633,10 @@ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md,  	req = blk_get_request(mq->queue,  		idata->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,  		__GFP_RECLAIM); +	if (IS_ERR(req)) { +		err = PTR_ERR(req); +		goto cmd_done; +	}  	idatas[0] = idata;  	req_to_mmc_queue_req(req)->drv_op =  		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL; @@ -691,6 +704,10 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md,  	req = blk_get_request(mq->queue,  		idata[0]->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,  		__GFP_RECLAIM); +	if (IS_ERR(req)) { +		err = PTR_ERR(req); +		goto cmd_err; +	}  	req_to_mmc_queue_req(req)->drv_op =  		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;  	req_to_mmc_queue_req(req)->drv_op_data = idata; @@ -2550,6 +2567,8 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)  	/* Ask the block layer about the card status */  	req = blk_get_request(mq->queue, REQ_OP_DRV_IN, __GFP_RECLAIM); +	if (IS_ERR(req)) +		return PTR_ERR(req);  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_CARD_STATUS;  	blk_execute_rq(mq->queue, NULL, req, 0);  	ret = req_to_mmc_queue_req(req)->drv_op_result; @@ -2557,6 +2576,7 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)  		*val = ret;  		ret = 0;  	} +	blk_put_request(req);  	return ret;  } @@ -2583,10 +2603,15 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)  	/* Ask the block layer for the EXT CSD */  	req = blk_get_request(mq->queue, REQ_OP_DRV_IN, __GFP_RECLAIM); +	if (IS_ERR(req)) { +		err = PTR_ERR(req); +		goto out_free; +	}  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_EXT_CSD;  	req_to_mmc_queue_req(req)->drv_op_data = &ext_csd;  	blk_execute_rq(mq->queue, NULL, req, 0);  	err = req_to_mmc_queue_req(req)->drv_op_result; +	blk_put_request(req);  	if (err) {  		pr_err("FAILED %d\n", err);  		goto out_free; @@ -2632,7 +2657,7 @@ static const struct file_operations mmc_dbg_ext_csd_fops = {  	.llseek		= default_llseek,  }; -static int mmc_blk_add_debugfs(struct mmc_card *card) +static int mmc_blk_add_debugfs(struct mmc_card *card, struct mmc_blk_data *md)  {  	struct dentry *root; @@ -2642,28 +2667,53 @@ static int mmc_blk_add_debugfs(struct mmc_card *card)  	root = card->debugfs_root;  	if (mmc_card_mmc(card) || mmc_card_sd(card)) { -		if (!debugfs_create_file("status", S_IRUSR, root, card, -					 &mmc_dbg_card_status_fops)) +		md->status_dentry = +			debugfs_create_file("status", S_IRUSR, root, card, +					    &mmc_dbg_card_status_fops); +		if (!md->status_dentry)  			return -EIO;  	}  	if (mmc_card_mmc(card)) { -		if (!debugfs_create_file("ext_csd", S_IRUSR, root, card, -					 &mmc_dbg_ext_csd_fops)) +		md->ext_csd_dentry = +			debugfs_create_file("ext_csd", S_IRUSR, root, card, +					    &mmc_dbg_ext_csd_fops); +		if (!md->ext_csd_dentry)  			return -EIO;  	}  	return 0;  } +static void mmc_blk_remove_debugfs(struct mmc_card *card, +				   struct mmc_blk_data *md) +{ +	if (!card->debugfs_root) +		return; + +	if (!IS_ERR_OR_NULL(md->status_dentry)) { +		debugfs_remove(md->status_dentry); +		md->status_dentry = NULL; +	} + +	if (!IS_ERR_OR_NULL(md->ext_csd_dentry)) { +		debugfs_remove(md->ext_csd_dentry); +		md->ext_csd_dentry = NULL; +	} +}  #else -static int mmc_blk_add_debugfs(struct mmc_card *card) +static int mmc_blk_add_debugfs(struct mmc_card *card, struct mmc_blk_data *md)  {  	return 0;  } +static void mmc_blk_remove_debugfs(struct mmc_card *card, +				   struct mmc_blk_data *md) +{ +} +  #endif /* CONFIG_DEBUG_FS */  static int mmc_blk_probe(struct mmc_card *card) @@ -2703,7 +2753,7 @@ static int mmc_blk_probe(struct mmc_card *card)  	}  	/* Add two debugfs entries */ -	mmc_blk_add_debugfs(card); +	mmc_blk_add_debugfs(card, md);  	pm_runtime_set_autosuspend_delay(&card->dev, 3000);  	pm_runtime_use_autosuspend(&card->dev); @@ -2729,6 +2779,7 @@ static void mmc_blk_remove(struct mmc_card *card)  {  	struct mmc_blk_data *md = dev_get_drvdata(&card->dev); +	mmc_blk_remove_debugfs(card, md);  	mmc_blk_remove_parts(card, md);  	pm_runtime_get_sync(&card->dev);  	mmc_claim_host(card->host);  | 
