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

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
...@@ -279,9 +279,8 @@ struct fsg_common { ...@@ -279,9 +279,8 @@ struct fsg_common {
int cmnd_size; int cmnd_size;
u8 cmnd[MAX_COMMAND_SIZE]; u8 cmnd[MAX_COMMAND_SIZE];
unsigned int nluns;
unsigned int lun; unsigned int lun;
struct fsg_lun **luns; struct fsg_lun *luns[FSG_MAX_LUNS];
struct fsg_lun *curlun; struct fsg_lun *curlun;
unsigned int bulk_out_maxpacket; unsigned int bulk_out_maxpacket;
...@@ -490,6 +489,16 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) ...@@ -490,6 +489,16 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
spin_unlock(&common->lock); 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, static int fsg_setup(struct usb_function *f,
const struct usb_ctrlrequest *ctrl) const struct usb_ctrlrequest *ctrl)
{ {
...@@ -533,7 +542,7 @@ static int fsg_setup(struct usb_function *f, ...@@ -533,7 +542,7 @@ static int fsg_setup(struct usb_function *f,
w_length != 1) w_length != 1)
return -EDOM; return -EDOM;
VDBG(fsg, "get max LUN\n"); 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 */ /* Respond with data/status */
req->length = min((u16)1, w_length); req->length = min((u16)1, w_length);
...@@ -2131,8 +2140,9 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) ...@@ -2131,8 +2140,9 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
} }
/* Is the CBW meaningful? */ /* Is the CBW meaningful? */
if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN || if (cbw->Lun >= ARRAY_SIZE(common->luns) ||
cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) { cbw->Flags & ~US_BULK_FLAG_IN || cbw->Length <= 0 ||
cbw->Length > MAX_COMMAND_SIZE) {
DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
"cmdlen %u\n", "cmdlen %u\n",
cbw->Lun, cbw->Flags, cbw->Length); cbw->Lun, cbw->Flags, cbw->Length);
...@@ -2159,7 +2169,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) ...@@ -2159,7 +2169,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
if (common->data_size == 0) if (common->data_size == 0)
common->data_dir = DATA_DIR_NONE; common->data_dir = DATA_DIR_NONE;
common->lun = cbw->Lun; common->lun = cbw->Lun;
if (common->lun < common->nluns) if (common->lun < ARRAY_SIZE(common->luns))
common->curlun = common->luns[common->lun]; common->curlun = common->luns[common->lun];
else else
common->curlun = NULL; common->curlun = NULL;
...@@ -2307,7 +2317,7 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) ...@@ -2307,7 +2317,7 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
} }
common->running = 1; common->running = 1;
for (i = 0; i < common->nluns; ++i) for (i = 0; i < ARRAY_SIZE(common->luns); ++i)
if (common->luns[i]) if (common->luns[i])
common->luns[i]->unit_attention_data = common->luns[i]->unit_attention_data =
SS_RESET_OCCURRED; SS_RESET_OCCURRED;
...@@ -2409,7 +2419,7 @@ static void handle_exception(struct fsg_common *common) ...@@ -2409,7 +2419,7 @@ static void handle_exception(struct fsg_common *common)
if (old_state == FSG_STATE_ABORT_BULK_OUT) if (old_state == FSG_STATE_ABORT_BULK_OUT)
common->state = FSG_STATE_STATUS_PHASE; common->state = FSG_STATE_STATUS_PHASE;
else { else {
for (i = 0; i < common->nluns; ++i) { for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
curlun = common->luns[i]; curlun = common->luns[i];
if (!curlun) if (!curlun)
continue; continue;
...@@ -2453,7 +2463,7 @@ static void handle_exception(struct fsg_common *common) ...@@ -2453,7 +2463,7 @@ static void handle_exception(struct fsg_common *common)
* a waste of time. Ditto for the INTERFACE_CHANGE and * a waste of time. Ditto for the INTERFACE_CHANGE and
* CONFIG_CHANGE cases. * CONFIG_CHANGE cases.
*/ */
/* for (i = 0; i < common->nluns; ++i) */ /* for (i = 0; i < common->ARRAY_SIZE(common->luns); ++i) */
/* if (common->luns[i]) */ /* if (common->luns[i]) */
/* common->luns[i]->unit_attention_data = */ /* common->luns[i]->unit_attention_data = */
/* SS_RESET_OCCURRED; */ /* SS_RESET_OCCURRED; */
...@@ -2552,12 +2562,11 @@ static int fsg_main_thread(void *common_) ...@@ -2552,12 +2562,11 @@ static int fsg_main_thread(void *common_)
if (!common->ops || !common->ops->thread_exits if (!common->ops || !common->ops->thread_exits
|| common->ops->thread_exits(common) < 0) { || common->ops->thread_exits(common) < 0) {
struct fsg_lun **curlun_it = common->luns; int i;
unsigned i = common->nluns;
down_write(&common->filesem); down_write(&common->filesem);
for (; i--; ++curlun_it) { for (i = 0; i < ARRAY_SIZE(common->luns); --i) {
struct fsg_lun *curlun = *curlun_it; struct fsg_lun *curlun = common->luns[i];
if (!curlun || !fsg_lun_is_open(curlun)) if (!curlun || !fsg_lun_is_open(curlun))
continue; continue;
...@@ -2676,6 +2685,7 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common) ...@@ -2676,6 +2685,7 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common)
init_completion(&common->thread_notifier); init_completion(&common->thread_notifier);
init_waitqueue_head(&common->fsg_wait); init_waitqueue_head(&common->fsg_wait);
common->state = FSG_STATE_TERMINATED; common->state = FSG_STATE_TERMINATED;
memset(common->luns, 0, sizeof(common->luns));
return common; return common;
} }
...@@ -2764,42 +2774,10 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n) ...@@ -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) 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); 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, void fsg_common_set_ops(struct fsg_common *common,
const struct fsg_operations *ops) const struct fsg_operations *ops)
{ {
...@@ -2881,7 +2859,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, ...@@ -2881,7 +2859,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
char *pathbuf, *p; char *pathbuf, *p;
int rc = -ENOMEM; int rc = -ENOMEM;
if (!common->nluns || !common->luns) if (id >= ARRAY_SIZE(common->luns))
return -ENODEV; return -ENODEV;
if (common->luns[id]) if (common->luns[id])
...@@ -2965,14 +2943,16 @@ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg) ...@@ -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 */ char buf[8]; /* enough for 100000000 different numbers, decimal */
int i, rc; 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); snprintf(buf, sizeof(buf), "lun%d", i);
rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL); rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
if (rc) if (rc)
goto fail; goto fail;
} }
pr_info("Number of LUNs=%d\n", common->nluns); pr_info("Number of LUNs=%d\n", cfg->nluns);
return 0; return 0;
...@@ -3021,6 +3001,7 @@ EXPORT_SYMBOL_GPL(fsg_common_run_thread); ...@@ -3021,6 +3001,7 @@ EXPORT_SYMBOL_GPL(fsg_common_run_thread);
static void fsg_common_release(struct kref *ref) static void fsg_common_release(struct kref *ref)
{ {
struct fsg_common *common = container_of(ref, struct fsg_common, 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 the thread isn't already dead, tell it to exit now */
if (common->state != FSG_STATE_TERMINATED) { if (common->state != FSG_STATE_TERMINATED) {
...@@ -3028,22 +3009,14 @@ static void fsg_common_release(struct kref *ref) ...@@ -3028,22 +3009,14 @@ static void fsg_common_release(struct kref *ref)
wait_for_completion(&common->thread_notifier); wait_for_completion(&common->thread_notifier);
} }
if (likely(common->luns)) { for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
struct fsg_lun **lun_it = common->luns; struct fsg_lun *lun = common->luns[i];
unsigned i = common->nluns; if (!lun)
continue;
/* In error recovery common->nluns may be zero. */ fsg_lun_close(lun);
for (; i; --i, ++lun_it) {
struct fsg_lun *lun = *lun_it;
if (!lun)
continue;
fsg_lun_close(lun);
if (device_is_registered(&lun->dev)) if (device_is_registered(&lun->dev))
device_unregister(&lun->dev); device_unregister(&lun->dev);
kfree(lun); kfree(lun);
}
kfree(common->luns);
} }
_fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
...@@ -3057,6 +3030,7 @@ static void fsg_common_release(struct kref *ref) ...@@ -3057,6 +3030,7 @@ static void fsg_common_release(struct kref *ref)
static int fsg_bind(struct usb_configuration *c, struct usb_function *f) static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
{ {
struct fsg_dev *fsg = fsg_from_func(f); struct fsg_dev *fsg = fsg_from_func(f);
struct fsg_common *common = fsg->common;
struct usb_gadget *gadget = c->cdev->gadget; struct usb_gadget *gadget = c->cdev->gadget;
int i; int i;
struct usb_ep *ep; struct usb_ep *ep;
...@@ -3064,6 +3038,13 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ...@@ -3064,6 +3038,13 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
int ret; int ret;
struct fsg_opts *opts; 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); opts = fsg_opts_from_func_inst(f->fi);
if (!opts->no_configfs) { if (!opts->no_configfs) {
ret = fsg_common_set_cdev(fsg->common, c->cdev, ret = fsg_common_set_cdev(fsg->common, c->cdev,
...@@ -3517,14 +3498,11 @@ static struct usb_function_instance *fsg_alloc_inst(void) ...@@ -3517,14 +3498,11 @@ static struct usb_function_instance *fsg_alloc_inst(void)
rc = PTR_ERR(opts->common); rc = PTR_ERR(opts->common);
goto release_opts; 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, rc = fsg_common_set_num_buffers(opts->common,
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS); CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
if (rc) if (rc)
goto release_luns; goto release_opts;
pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
...@@ -3547,8 +3525,6 @@ static struct usb_function_instance *fsg_alloc_inst(void) ...@@ -3547,8 +3525,6 @@ static struct usb_function_instance *fsg_alloc_inst(void)
release_buffers: release_buffers:
fsg_common_free_buffers(opts->common); fsg_common_free_buffers(opts->common);
release_luns:
kfree(opts->common->luns);
release_opts: release_opts:
kfree(opts); kfree(opts);
return ERR_PTR(rc); return ERR_PTR(rc);
...@@ -3574,23 +3550,12 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi) ...@@ -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_opts *opts = fsg_opts_from_func_inst(fi);
struct fsg_common *common = opts->common; struct fsg_common *common = opts->common;
struct fsg_dev *fsg; struct fsg_dev *fsg;
unsigned nluns, i;
fsg = kzalloc(sizeof(*fsg), GFP_KERNEL); fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
if (unlikely(!fsg)) if (unlikely(!fsg))
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
mutex_lock(&opts->lock); 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++; opts->refcnt++;
mutex_unlock(&opts->lock); mutex_unlock(&opts->lock);
......
...@@ -141,10 +141,6 @@ void fsg_common_remove_lun(struct fsg_lun *lun); ...@@ -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_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, void fsg_common_set_ops(struct fsg_common *common,
const struct fsg_operations *ops); const struct fsg_operations *ops);
......
...@@ -186,10 +186,6 @@ static int acm_ms_bind(struct usb_composite_dev *cdev) ...@@ -186,10 +186,6 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
if (status) if (status)
goto fail; 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); status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
if (status) if (status)
goto fail_set_cdev; goto fail_set_cdev;
...@@ -239,8 +235,6 @@ static int acm_ms_bind(struct usb_composite_dev *cdev) ...@@ -239,8 +235,6 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
fail_string_ids: fail_string_ids:
fsg_common_remove_luns(opts->common); fsg_common_remove_luns(opts->common);
fail_set_cdev: fail_set_cdev:
fsg_common_free_luns(opts->common);
fail_set_nluns:
fsg_common_free_buffers(opts->common); fsg_common_free_buffers(opts->common);
fail: fail:
usb_put_function_instance(fi_msg); usb_put_function_instance(fi_msg);
......
...@@ -177,10 +177,6 @@ static int msg_bind(struct usb_composite_dev *cdev) ...@@ -177,10 +177,6 @@ static int msg_bind(struct usb_composite_dev *cdev)
if (status) if (status)
goto fail; goto fail;
status = fsg_common_set_nluns(opts->common, config.nluns);
if (status)
goto fail_set_nluns;
fsg_common_set_ops(opts->common, &ops); fsg_common_set_ops(opts->common, &ops);
status = fsg_common_set_cdev(opts->common, cdev, config.can_stall); status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
...@@ -227,8 +223,6 @@ static int msg_bind(struct usb_composite_dev *cdev) ...@@ -227,8 +223,6 @@ static int msg_bind(struct usb_composite_dev *cdev)
fail_string_ids: fail_string_ids:
fsg_common_remove_luns(opts->common); fsg_common_remove_luns(opts->common);
fail_set_cdev: fail_set_cdev:
fsg_common_free_luns(opts->common);
fail_set_nluns:
fsg_common_free_buffers(opts->common); fsg_common_free_buffers(opts->common);
fail: fail:
usb_put_function_instance(fi_msg); usb_put_function_instance(fi_msg);
......
...@@ -393,10 +393,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) ...@@ -393,10 +393,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
if (status) if (status)
goto fail2; 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); status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
if (status) if (status)
goto fail_set_cdev; goto fail_set_cdev;
...@@ -448,8 +444,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) ...@@ -448,8 +444,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
fail_string_ids: fail_string_ids:
fsg_common_remove_luns(fsg_opts->common); fsg_common_remove_luns(fsg_opts->common);
fail_set_cdev: fail_set_cdev:
fsg_common_free_luns(fsg_opts->common);
fail_set_nluns:
fsg_common_free_buffers(fsg_opts->common); fsg_common_free_buffers(fsg_opts->common);
fail2: fail2:
usb_put_function_instance(fi_msg); usb_put_function_instance(fi_msg);
......
...@@ -339,19 +339,15 @@ static int nokia_bind(struct usb_composite_dev *cdev) ...@@ -339,19 +339,15 @@ static int nokia_bind(struct usb_composite_dev *cdev)
if (status) if (status)
goto err_msg_inst; goto err_msg_inst;
status = fsg_common_set_nluns(fsg_opts->common, fsg_config.nluns);
if (status)
goto err_msg_buf;
status = fsg_common_set_cdev(fsg_opts->common, cdev, fsg_config.can_stall); status = fsg_common_set_cdev(fsg_opts->common, cdev, fsg_config.can_stall);
if (status) if (status)
goto err_msg_set_nluns; goto err_msg_buf;
fsg_common_set_sysfs(fsg_opts->common, true); fsg_common_set_sysfs(fsg_opts->common, true);
status = fsg_common_create_luns(fsg_opts->common, &fsg_config); status = fsg_common_create_luns(fsg_opts->common, &fsg_config);
if (status) if (status)
goto err_msg_set_nluns; goto err_msg_buf;
fsg_common_set_inquiry_string(fsg_opts->common, fsg_config.vendor_name, fsg_common_set_inquiry_string(fsg_opts->common, fsg_config.vendor_name,
fsg_config.product_name); fsg_config.product_name);
...@@ -360,7 +356,7 @@ static int nokia_bind(struct usb_composite_dev *cdev) ...@@ -360,7 +356,7 @@ static int nokia_bind(struct usb_composite_dev *cdev)
status = usb_add_config(cdev, &nokia_config_500ma_driver, status = usb_add_config(cdev, &nokia_config_500ma_driver,
nokia_bind_config); nokia_bind_config);
if (status < 0) if (status < 0)
goto err_msg_set_cdev; goto err_msg_luns;
status = usb_add_config(cdev, &nokia_config_100ma_driver, status = usb_add_config(cdev, &nokia_config_100ma_driver,
nokia_bind_config); nokia_bind_config);
...@@ -381,10 +377,8 @@ static int nokia_bind(struct usb_composite_dev *cdev) ...@@ -381,10 +377,8 @@ static int nokia_bind(struct usb_composite_dev *cdev)
if (!IS_ERR_OR_NULL(f_phonet_cfg1)) if (!IS_ERR_OR_NULL(f_phonet_cfg1))
usb_put_function(f_phonet_cfg1); usb_put_function(f_phonet_cfg1);
usb_put_function(f_ecm_cfg1); usb_put_function(f_ecm_cfg1);
err_msg_set_cdev: err_msg_luns:
fsg_common_remove_luns(fsg_opts->common); fsg_common_remove_luns(fsg_opts->common);
err_msg_set_nluns:
fsg_common_free_luns(fsg_opts->common);
err_msg_buf: err_msg_buf:
fsg_common_free_buffers(fsg_opts->common); fsg_common_free_buffers(fsg_opts->common);
err_msg_inst: err_msg_inst:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment