diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/usb/gadget/function/f_mass_storage.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/usb/gadget/function/f_mass_storage.c')
-rw-r--r-- | kernel/drivers/usb/gadget/function/f_mass_storage.c | 299 |
1 files changed, 123 insertions, 176 deletions
diff --git a/kernel/drivers/usb/gadget/function/f_mass_storage.c b/kernel/drivers/usb/gadget/function/f_mass_storage.c index 15c307155..223ccf89d 100644 --- a/kernel/drivers/usb/gadget/function/f_mass_storage.c +++ b/kernel/drivers/usb/gadget/function/f_mass_storage.c @@ -54,7 +54,7 @@ * following fields: * * nluns Number of LUNs function have (anywhere from 1 - * to FSG_MAX_LUNS which is 8). + * to FSG_MAX_LUNS). * luns An array of LUN configuration values. This * should be filled for each LUN that * function will include (ie. for "nluns" @@ -214,12 +214,12 @@ #include <linux/string.h> #include <linux/freezer.h> #include <linux/module.h> +#include <linux/uaccess.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <linux/usb/composite.h> -#include "gadget_chips.h" #include "configfs.h" @@ -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; @@ -2248,12 +2258,10 @@ reset: /* Disable the endpoints */ if (fsg->bulk_in_enabled) { usb_ep_disable(fsg->bulk_in); - fsg->bulk_in->driver_data = NULL; fsg->bulk_in_enabled = 0; } if (fsg->bulk_out_enabled) { usb_ep_disable(fsg->bulk_out); - fsg->bulk_out->driver_data = NULL; fsg->bulk_out_enabled = 0; } @@ -2307,7 +2315,7 @@ reset: } 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; @@ -2337,7 +2345,6 @@ static void fsg_disable(struct usb_function *f) static void handle_exception(struct fsg_common *common) { - siginfo_t info; int i; struct fsg_buffhd *bh; enum fsg_state old_state; @@ -2349,8 +2356,7 @@ static void handle_exception(struct fsg_common *common) * into a high-priority EXIT exception. */ for (;;) { - int sig = - dequeue_signal_lock(current, ¤t->blocked, &info); + int sig = kernel_dequeue_signal(NULL); if (!sig) break; if (sig != SIGUSR1) { @@ -2409,7 +2415,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 +2459,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 +2558,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; @@ -2653,10 +2658,12 @@ EXPORT_SYMBOL_GPL(fsg_common_put); /* check if fsg_num_buffers is within a valid range */ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) { - if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4) +#define FSG_MAX_NUM_BUFFERS 32 + + if (fsg_num_buffers >= 2 && fsg_num_buffers <= FSG_MAX_NUM_BUFFERS) return 0; pr_err("fsg_num_buffers %u is out of range (%d to %d)\n", - fsg_num_buffers, 2, 4); + fsg_num_buffers, 2, FSG_MAX_NUM_BUFFERS); return -EINVAL; } @@ -2676,6 +2683,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; } @@ -2742,9 +2750,9 @@ error_release: } EXPORT_SYMBOL_GPL(fsg_common_set_num_buffers); -void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs) +void fsg_common_remove_lun(struct fsg_lun *lun) { - if (sysfs) + if (device_is_registered(&lun->dev)) device_unregister(&lun->dev); fsg_lun_close(lun); kfree(lun); @@ -2757,48 +2765,16 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n) for (i = 0; i < n; ++i) if (common->luns[i]) { - fsg_common_remove_lun(common->luns[i], common->sysfs); + fsg_common_remove_lun(common->luns[i]); common->luns[i] = NULL; } } -EXPORT_SYMBOL_GPL(fsg_common_remove_luns); void fsg_common_remove_luns(struct fsg_common *common) { - _fsg_common_remove_luns(common, common->nluns); -} - -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; + _fsg_common_remove_luns(common, ARRAY_SIZE(common->luns)); } -EXPORT_SYMBOL_GPL(fsg_common_set_nluns); +EXPORT_SYMBOL_GPL(fsg_common_remove_luns); void fsg_common_set_ops(struct fsg_common *common, const struct fsg_operations *ops) @@ -2836,7 +2812,8 @@ int fsg_common_set_cdev(struct fsg_common *common, * halt bulk endpoints correctly. If one of them is present, * disable stalls. */ - common->can_stall = can_stall && !(gadget_is_at91(common->gadget)); + common->can_stall = can_stall && + gadget_is_stall_supported(common->gadget); return 0; } @@ -2880,7 +2857,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]) @@ -2934,7 +2911,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, if (fsg_lun_is_open(lun)) { p = "(error)"; if (pathbuf) { - p = d_path(&lun->filp->f_path, pathbuf, PATH_MAX); + p = file_path(lun->filp, pathbuf, PATH_MAX); if (IS_ERR(p)) p = "(error)"; } @@ -2949,7 +2926,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, return 0; error_lun: - if (common->sysfs) + if (device_is_registered(&lun->dev)) device_unregister(&lun->dev); fsg_lun_close(lun); common->luns[id] = NULL; @@ -2964,14 +2941,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; @@ -3020,6 +2999,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) { @@ -3027,22 +3007,14 @@ 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; - if (!lun) - continue; - fsg_lun_close(lun); - if (common->sysfs) - device_unregister(&lun->dev); - kfree(lun); - } - - kfree(common->luns); + 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); } _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); @@ -3056,6 +3028,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; @@ -3063,6 +3036,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, @@ -3080,7 +3060,7 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) /* New interface */ i = usb_interface_id(c, f); if (i < 0) - return i; + goto fail; fsg_intf_desc.bInterfaceNumber = i; fsg->interface_number = i; @@ -3088,13 +3068,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); if (!ep) goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_in = ep; ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc); if (!ep) goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_out = ep; /* Assume endpoint addresses are the same for both speeds */ @@ -3123,7 +3101,14 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) autoconf_fail: ERROR(fsg, "unable to autoconfigure all endpoints\n"); - return -ENOTSUPP; + i = -ENOTSUPP; +fail: + /* terminate the thread */ + if (fsg->common->state != FSG_STATE_TERMINATED) { + raise_exception(fsg->common, FSG_STATE_EXIT); + wait_for_completion(&fsg->common->thread_notifier); + } + return i; } /****************************** ALLOCATE FUNCTION *************************/ @@ -3155,9 +3140,6 @@ static inline struct fsg_opts *to_fsg_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(fsg_lun_opts); -CONFIGFS_ATTR_OPS(fsg_lun_opts); - static void fsg_lun_attr_release(struct config_item *item) { struct fsg_lun_opts *lun_opts; @@ -3168,110 +3150,93 @@ static void fsg_lun_attr_release(struct config_item *item) static struct configfs_item_operations fsg_lun_item_ops = { .release = fsg_lun_attr_release, - .show_attribute = fsg_lun_opts_attr_show, - .store_attribute = fsg_lun_opts_attr_store, }; -static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page) +static ssize_t fsg_lun_opts_file_show(struct config_item *item, char *page) { - struct fsg_opts *fsg_opts; - - fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); + struct fsg_lun_opts *opts = to_fsg_lun_opts(item); + struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page); } -static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_file_store(struct config_item *item, const char *page, size_t len) { - struct fsg_opts *fsg_opts; - - fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); + struct fsg_lun_opts *opts = to_fsg_lun_opts(item); + struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_file = - __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show, - fsg_lun_opts_file_store); +CONFIGFS_ATTR(fsg_lun_opts_, file); -static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page) +static ssize_t fsg_lun_opts_ro_show(struct config_item *item, char *page) { - return fsg_show_ro(opts->lun, page); + return fsg_show_ro(to_fsg_lun_opts(item)->lun, page); } -static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_ro_store(struct config_item *item, const char *page, size_t len) { - struct fsg_opts *fsg_opts; - - fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); + struct fsg_lun_opts *opts = to_fsg_lun_opts(item); + struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_ro = - __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show, - fsg_lun_opts_ro_store); +CONFIGFS_ATTR(fsg_lun_opts_, ro); -static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_removable_show(struct config_item *item, char *page) { - return fsg_show_removable(opts->lun, page); + return fsg_show_removable(to_fsg_lun_opts(item)->lun, page); } -static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_removable_store(struct config_item *item, const char *page, size_t len) { - return fsg_store_removable(opts->lun, page, len); + return fsg_store_removable(to_fsg_lun_opts(item)->lun, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_removable = - __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR, - fsg_lun_opts_removable_show, - fsg_lun_opts_removable_store); +CONFIGFS_ATTR(fsg_lun_opts_, removable); -static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page) +static ssize_t fsg_lun_opts_cdrom_show(struct config_item *item, char *page) { - return fsg_show_cdrom(opts->lun, page); + return fsg_show_cdrom(to_fsg_lun_opts(item)->lun, page); } -static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_cdrom_store(struct config_item *item, const char *page, size_t len) { - struct fsg_opts *fsg_opts; - - fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); + struct fsg_lun_opts *opts = to_fsg_lun_opts(item); + struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom = - __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show, - fsg_lun_opts_cdrom_store); +CONFIGFS_ATTR(fsg_lun_opts_, cdrom); -static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page) +static ssize_t fsg_lun_opts_nofua_show(struct config_item *item, char *page) { - return fsg_show_nofua(opts->lun, page); + return fsg_show_nofua(to_fsg_lun_opts(item)->lun, page); } -static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_nofua_store(struct config_item *item, const char *page, size_t len) { - return fsg_store_nofua(opts->lun, page, len); + return fsg_store_nofua(to_fsg_lun_opts(item)->lun, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_nofua = - __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show, - fsg_lun_opts_nofua_store); +CONFIGFS_ATTR(fsg_lun_opts_, nofua); static struct configfs_attribute *fsg_lun_attrs[] = { - &fsg_lun_opts_file.attr, - &fsg_lun_opts_ro.attr, - &fsg_lun_opts_removable.attr, - &fsg_lun_opts_cdrom.attr, - &fsg_lun_opts_nofua.attr, + &fsg_lun_opts_attr_file, + &fsg_lun_opts_attr_ro, + &fsg_lun_opts_attr_removable, + &fsg_lun_opts_attr_cdrom, + &fsg_lun_opts_attr_nofua, NULL, }; @@ -3355,7 +3320,7 @@ static void fsg_lun_drop(struct config_group *group, struct config_item *item) unregister_gadget_item(gadget); } - fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs); + fsg_common_remove_lun(lun_opts->lun); fsg_opts->common->luns[lun_opts->lun_id] = NULL; lun_opts->lun_id = 0; mutex_unlock(&fsg_opts->lock); @@ -3363,9 +3328,6 @@ static void fsg_lun_drop(struct config_group *group, struct config_item *item) config_item_put(item); } -CONFIGFS_ATTR_STRUCT(fsg_opts); -CONFIGFS_ATTR_OPS(fsg_opts); - static void fsg_attr_release(struct config_item *item) { struct fsg_opts *opts = to_fsg_opts(item); @@ -3375,12 +3337,11 @@ static void fsg_attr_release(struct config_item *item) static struct configfs_item_operations fsg_item_ops = { .release = fsg_attr_release, - .show_attribute = fsg_opts_attr_show, - .store_attribute = fsg_opts_attr_store, }; -static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page) +static ssize_t fsg_opts_stall_show(struct config_item *item, char *page) { + struct fsg_opts *opts = to_fsg_opts(item); int result; mutex_lock(&opts->lock); @@ -3390,9 +3351,10 @@ static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page) return result; } -static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page, +static ssize_t fsg_opts_stall_store(struct config_item *item, const char *page, size_t len) { + struct fsg_opts *opts = to_fsg_opts(item); int ret; bool stall; @@ -3414,13 +3376,12 @@ static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page, return ret; } -static struct fsg_opts_attribute fsg_opts_stall = - __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show, - fsg_opts_stall_store); +CONFIGFS_ATTR(fsg_opts_, stall); #ifdef CONFIG_USB_GADGET_DEBUG_FILES -static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page) +static ssize_t fsg_opts_num_buffers_show(struct config_item *item, char *page) { + struct fsg_opts *opts = to_fsg_opts(item); int result; mutex_lock(&opts->lock); @@ -3430,9 +3391,10 @@ static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page) return result; } -static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts, +static ssize_t fsg_opts_num_buffers_store(struct config_item *item, const char *page, size_t len) { + struct fsg_opts *opts = to_fsg_opts(item); int ret; u8 num; @@ -3457,17 +3419,13 @@ end: return ret; } -static struct fsg_opts_attribute fsg_opts_num_buffers = - __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR, - fsg_opts_num_buffers_show, - fsg_opts_num_buffers_store); - +CONFIGFS_ATTR(fsg_opts_, num_buffers); #endif static struct configfs_attribute *fsg_attrs[] = { - &fsg_opts_stall.attr, + &fsg_opts_attr_stall, #ifdef CONFIG_USB_GADGET_DEBUG_FILES - &fsg_opts_num_buffers.attr, + &fsg_opts_attr_num_buffers, #endif NULL, }; @@ -3509,14 +3467,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"); @@ -3524,6 +3479,9 @@ static struct usb_function_instance *fsg_alloc_inst(void) config.removable = true; rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0", (const char **)&opts->func_inst.group.cg_item.ci_name); + if (rc) + goto release_buffers; + opts->lun0.lun = opts->common->luns[0]; opts->lun0.lun_id = 0; config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type); @@ -3534,8 +3492,8 @@ static struct usb_function_instance *fsg_alloc_inst(void) return &opts->func_inst; -release_luns: - kfree(opts->common->luns); +release_buffers: + fsg_common_free_buffers(opts->common); release_opts: kfree(opts); return ERR_PTR(rc); @@ -3561,23 +3519,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); |