Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd02ea5a authored by Krzysztof Opasiak's avatar Krzysztof Opasiak Committed by Felipe Balbi
Browse files

usb: gadget: mass_storage: Use static array for luns



This patch replace dynamicly allocated luns array with static one.
This simplifies the code of mass storage function and modules.

Signed-off-by: default avatarKrzysztof Opasiak <k.opasiak@samsung.com>
Acked-by: default avatarMichal Nazarewicz <mina86@mina86.com>
parent 5542f58c
Loading
Loading
Loading
Loading
+46 −81
Original line number Diff line number Diff line
@@ -279,9 +279,8 @@ struct fsg_common {
	int			cmnd_size;
	u8			cmnd[MAX_COMMAND_SIZE];

	unsigned int		nluns;
	unsigned int		lun;
	struct fsg_lun		**luns;
	struct fsg_lun		*luns[FSG_MAX_LUNS];
	struct fsg_lun		*curlun;

	unsigned int		bulk_out_maxpacket;
@@ -490,6 +489,16 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
	spin_unlock(&common->lock);
}

static int _fsg_common_get_max_lun(struct fsg_common *common)
{
	int i = ARRAY_SIZE(common->luns) - 1;

	while (i >= 0 && !common->luns[i])
		--i;

	return i;
}

static int fsg_setup(struct usb_function *f,
		     const struct usb_ctrlrequest *ctrl)
{
@@ -533,7 +542,7 @@ static int fsg_setup(struct usb_function *f,
				w_length != 1)
			return -EDOM;
		VDBG(fsg, "get max LUN\n");
		*(u8 *)req->buf = fsg->common->nluns - 1;
		*(u8 *)req->buf = _fsg_common_get_max_lun(fsg->common);

		/* Respond with data/status */
		req->length = min((u16)1, w_length);
@@ -2131,8 +2140,9 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
	}

	/* Is the CBW meaningful? */
	if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN ||
			cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
	if (cbw->Lun >= ARRAY_SIZE(common->luns) ||
	    cbw->Flags & ~US_BULK_FLAG_IN || cbw->Length <= 0 ||
	    cbw->Length > MAX_COMMAND_SIZE) {
		DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
				"cmdlen %u\n",
				cbw->Lun, cbw->Flags, cbw->Length);
@@ -2159,7 +2169,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
	if (common->data_size == 0)
		common->data_dir = DATA_DIR_NONE;
	common->lun = cbw->Lun;
	if (common->lun < common->nluns)
	if (common->lun < ARRAY_SIZE(common->luns))
		common->curlun = common->luns[common->lun];
	else
		common->curlun = NULL;
@@ -2307,7 +2317,7 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
	}

	common->running = 1;
	for (i = 0; i < common->nluns; ++i)
	for (i = 0; i < ARRAY_SIZE(common->luns); ++i)
		if (common->luns[i])
			common->luns[i]->unit_attention_data =
				SS_RESET_OCCURRED;
@@ -2409,7 +2419,7 @@ static void handle_exception(struct fsg_common *common)
	if (old_state == FSG_STATE_ABORT_BULK_OUT)
		common->state = FSG_STATE_STATUS_PHASE;
	else {
		for (i = 0; i < common->nluns; ++i) {
		for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
			curlun = common->luns[i];
			if (!curlun)
				continue;
@@ -2453,7 +2463,7 @@ static void handle_exception(struct fsg_common *common)
		 * a waste of time.  Ditto for the INTERFACE_CHANGE and
		 * CONFIG_CHANGE cases.
		 */
		/* for (i = 0; i < common->nluns; ++i) */
		/* for (i = 0; i < common->ARRAY_SIZE(common->luns); ++i) */
		/*	if (common->luns[i]) */
		/*		common->luns[i]->unit_attention_data = */
		/*			SS_RESET_OCCURRED;  */
@@ -2552,12 +2562,11 @@ static int fsg_main_thread(void *common_)

	if (!common->ops || !common->ops->thread_exits
	 || common->ops->thread_exits(common) < 0) {
		struct fsg_lun **curlun_it = common->luns;
		unsigned i = common->nluns;
		int i;

		down_write(&common->filesem);
		for (; i--; ++curlun_it) {
			struct fsg_lun *curlun = *curlun_it;
		for (i = 0; i < ARRAY_SIZE(common->luns); --i) {
			struct fsg_lun *curlun = common->luns[i];
			if (!curlun || !fsg_lun_is_open(curlun))
				continue;

@@ -2676,6 +2685,7 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common)
	init_completion(&common->thread_notifier);
	init_waitqueue_head(&common->fsg_wait);
	common->state = FSG_STATE_TERMINATED;
	memset(common->luns, 0, sizeof(common->luns));

	return common;
}
@@ -2764,42 +2774,10 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n)

void fsg_common_remove_luns(struct fsg_common *common)
{
	_fsg_common_remove_luns(common, common->nluns);
	_fsg_common_remove_luns(common, ARRAY_SIZE(common->luns));
}
EXPORT_SYMBOL_GPL(fsg_common_remove_luns);

void fsg_common_free_luns(struct fsg_common *common)
{
	fsg_common_remove_luns(common);
	kfree(common->luns);
	common->luns = NULL;
}
EXPORT_SYMBOL_GPL(fsg_common_free_luns);

int fsg_common_set_nluns(struct fsg_common *common, int nluns)
{
	struct fsg_lun **curlun;

	/* Find out how many LUNs there should be */
	if (nluns < 1 || nluns > FSG_MAX_LUNS) {
		pr_err("invalid number of LUNs: %u\n", nluns);
		return -EINVAL;
	}

	curlun = kcalloc(FSG_MAX_LUNS, sizeof(*curlun), GFP_KERNEL);
	if (unlikely(!curlun))
		return -ENOMEM;

	if (common->luns)
		fsg_common_free_luns(common);

	common->luns = curlun;
	common->nluns = nluns;

	return 0;
}
EXPORT_SYMBOL_GPL(fsg_common_set_nluns);

void fsg_common_set_ops(struct fsg_common *common,
			const struct fsg_operations *ops)
{
@@ -2881,7 +2859,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
	char *pathbuf, *p;
	int rc = -ENOMEM;

	if (!common->nluns || !common->luns)
	if (id >= ARRAY_SIZE(common->luns))
		return -ENODEV;

	if (common->luns[id])
@@ -2965,14 +2943,16 @@ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
	char buf[8]; /* enough for 100000000 different numbers, decimal */
	int i, rc;

	for (i = 0; i < common->nluns; ++i) {
	fsg_common_remove_luns(common);

	for (i = 0; i < cfg->nluns; ++i) {
		snprintf(buf, sizeof(buf), "lun%d", i);
		rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
		if (rc)
			goto fail;
	}

	pr_info("Number of LUNs=%d\n", common->nluns);
	pr_info("Number of LUNs=%d\n", cfg->nluns);

	return 0;

@@ -3021,6 +3001,7 @@ EXPORT_SYMBOL_GPL(fsg_common_run_thread);
static void fsg_common_release(struct kref *ref)
{
	struct fsg_common *common = container_of(ref, struct fsg_common, ref);
	int i;

	/* If the thread isn't already dead, tell it to exit now */
	if (common->state != FSG_STATE_TERMINATED) {
@@ -3028,13 +3009,8 @@ static void fsg_common_release(struct kref *ref)
		wait_for_completion(&common->thread_notifier);
	}

	if (likely(common->luns)) {
		struct fsg_lun **lun_it = common->luns;
		unsigned i = common->nluns;

		/* In error recovery common->nluns may be zero. */
		for (; i; --i, ++lun_it) {
			struct fsg_lun *lun = *lun_it;
	for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
		struct fsg_lun *lun = common->luns[i];
		if (!lun)
			continue;
		fsg_lun_close(lun);
@@ -3043,9 +3019,6 @@ static void fsg_common_release(struct kref *ref)
		kfree(lun);
	}

		kfree(common->luns);
	}

	_fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
	if (common->free_storage_on_release)
		kfree(common);
@@ -3057,6 +3030,7 @@ static void fsg_common_release(struct kref *ref)
static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
{
	struct fsg_dev		*fsg = fsg_from_func(f);
	struct fsg_common	*common = fsg->common;
	struct usb_gadget	*gadget = c->cdev->gadget;
	int			i;
	struct usb_ep		*ep;
@@ -3064,6 +3038,13 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
	int			ret;
	struct fsg_opts		*opts;

	/* Don't allow to bind if we don't have at least one LUN */
	ret = _fsg_common_get_max_lun(common);
	if (ret < 0) {
		pr_err("There should be at least one LUN.\n");
		return -EINVAL;
	}

	opts = fsg_opts_from_func_inst(f->fi);
	if (!opts->no_configfs) {
		ret = fsg_common_set_cdev(fsg->common, c->cdev,
@@ -3517,14 +3498,11 @@ static struct usb_function_instance *fsg_alloc_inst(void)
		rc = PTR_ERR(opts->common);
		goto release_opts;
	}
	rc = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS);
	if (rc)
		goto release_opts;

	rc = fsg_common_set_num_buffers(opts->common,
					CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
	if (rc)
		goto release_luns;
		goto release_opts;

	pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");

@@ -3547,8 +3525,6 @@ static struct usb_function_instance *fsg_alloc_inst(void)

release_buffers:
	fsg_common_free_buffers(opts->common);
release_luns:
	kfree(opts->common->luns);
release_opts:
	kfree(opts);
	return ERR_PTR(rc);
@@ -3574,23 +3550,12 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
	struct fsg_opts *opts = fsg_opts_from_func_inst(fi);
	struct fsg_common *common = opts->common;
	struct fsg_dev *fsg;
	unsigned nluns, i;

	fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
	if (unlikely(!fsg))
		return ERR_PTR(-ENOMEM);

	mutex_lock(&opts->lock);
	if (!opts->refcnt) {
		for (nluns = i = 0; i < FSG_MAX_LUNS; ++i)
			if (common->luns[i])
				nluns = i + 1;
		if (!nluns)
			pr_warn("No LUNS defined, continuing anyway\n");
		else
			common->nluns = nluns;
		pr_info("Number of LUNs=%u\n", common->nluns);
	}
	opts->refcnt++;
	mutex_unlock(&opts->lock);

+0 −4
Original line number Diff line number Diff line
@@ -141,10 +141,6 @@ void fsg_common_remove_lun(struct fsg_lun *lun);

void fsg_common_remove_luns(struct fsg_common *common);

void fsg_common_free_luns(struct fsg_common *common);

int fsg_common_set_nluns(struct fsg_common *common, int nluns);

void fsg_common_set_ops(struct fsg_common *common,
			const struct fsg_operations *ops);

+0 −6
Original line number Diff line number Diff line
@@ -186,10 +186,6 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
	if (status)
		goto fail;

	status = fsg_common_set_nluns(opts->common, config.nluns);
	if (status)
		goto fail_set_nluns;

	status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
	if (status)
		goto fail_set_cdev;
@@ -239,8 +235,6 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
fail_string_ids:
	fsg_common_remove_luns(opts->common);
fail_set_cdev:
	fsg_common_free_luns(opts->common);
fail_set_nluns:
	fsg_common_free_buffers(opts->common);
fail:
	usb_put_function_instance(fi_msg);
+0 −6
Original line number Diff line number Diff line
@@ -177,10 +177,6 @@ static int msg_bind(struct usb_composite_dev *cdev)
	if (status)
		goto fail;

	status = fsg_common_set_nluns(opts->common, config.nluns);
	if (status)
		goto fail_set_nluns;

	fsg_common_set_ops(opts->common, &ops);

	status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
@@ -227,8 +223,6 @@ static int msg_bind(struct usb_composite_dev *cdev)
fail_string_ids:
	fsg_common_remove_luns(opts->common);
fail_set_cdev:
	fsg_common_free_luns(opts->common);
fail_set_nluns:
	fsg_common_free_buffers(opts->common);
fail:
	usb_put_function_instance(fi_msg);
+0 −6
Original line number Diff line number Diff line
@@ -393,10 +393,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
	if (status)
		goto fail2;

	status = fsg_common_set_nluns(fsg_opts->common, config.nluns);
	if (status)
		goto fail_set_nluns;

	status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
	if (status)
		goto fail_set_cdev;
@@ -448,8 +444,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
fail_string_ids:
	fsg_common_remove_luns(fsg_opts->common);
fail_set_cdev:
	fsg_common_free_luns(fsg_opts->common);
fail_set_nluns:
	fsg_common_free_buffers(fsg_opts->common);
fail2:
	usb_put_function_instance(fi_msg);
Loading