Skip to content

Commit

Permalink
usb: gadget: mass_storage: Use static array for luns
Browse files Browse the repository at this point in the history
This patch replace dynamicly allocated luns array with static one.
This simplifies the code of mass storage function and modules.

Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
  • Loading branch information
Krzysztof Opasiak authored and Felipe Balbi committed Jul 31, 2015
1 parent 5542f58 commit dd02ea5
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 113 deletions.
127 changes: 46 additions & 81 deletions drivers/usb/gadget/function/f_mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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; */
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -3021,29 +3001,22 @@ 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) {
raise_exception(common, FSG_STATE_EXIT);
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;
if (!lun)
continue;
fsg_lun_close(lun);
for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
struct fsg_lun *lun = common->luns[i];
if (!lun)
continue;
fsg_lun_close(lun);
if (device_is_registered(&lun->dev))
device_unregister(&lun->dev);
kfree(lun);
}

kfree(common->luns);
device_unregister(&lun->dev);
kfree(lun);
}

_fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
Expand All @@ -3057,13 +3030,21 @@ 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;
unsigned max_burst;
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,
Expand Down Expand Up @@ -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");

Expand All @@ -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);
Expand All @@ -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);

Expand Down
4 changes: 0 additions & 4 deletions drivers/usb/gadget/function/f_mass_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 0 additions & 6 deletions drivers/usb/gadget/legacy/acm_ms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 0 additions & 6 deletions drivers/usb/gadget/legacy/mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 0 additions & 6 deletions drivers/usb/gadget/legacy/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit dd02ea5

Please sign in to comment.