{
kref_get(&common->ref);
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_get);
+#endif
void fsg_common_put(struct fsg_common *common)
{
kref_put(&common->ref, fsg_common_release);
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_put);
+#endif
/* check if fsg_num_buffers is within a valid range */
static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
{
common->sysfs = sysfs;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_set_sysfs);
+#endif
static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
{
return -ENOMEM;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_set_num_buffers);
+#endif
void fsg_common_free_buffers(struct fsg_common *common)
{
_fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
common->buffhds = NULL;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_free_buffers);
+#endif
int fsg_common_set_nluns(struct fsg_common *common, int nluns)
{
return 0;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_set_nluns);
+#endif
void fsg_common_free_luns(struct fsg_common *common)
{
kfree(common->luns);
common->luns = NULL;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_free_luns);
+#endif
void fsg_common_set_ops(struct fsg_common *common,
const struct fsg_operations *ops)
{
common->ops = ops;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_set_ops);
+#endif
void fsg_common_set_private_data(struct fsg_common *common, void *priv)
{
common->private_data = priv;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_set_private_data);
+#endif
int fsg_common_set_cdev(struct fsg_common *common,
struct usb_composite_dev *cdev, bool can_stall)
return 0;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_set_cdev);
+#endif
static inline int fsg_common_add_sysfs(struct fsg_common *common,
struct fsg_lun *lun)
kfree(lun->name);
kfree(lun);
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_remove_lun);
+#endif
void _fsg_common_remove_luns(struct fsg_common *common, int n)
{
{
_fsg_common_remove_luns(common, common->nluns);
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_remove_luns);
+#endif
#define MAX_LUN_NAME_LEN 80
kfree(lun);
return rc;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_create_lun);
+#endif
int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
{
_fsg_common_remove_luns(common, i);
return rc;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_create_luns);
+#endif
void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
const char *pn)
: "File-Stor Gadget"),
i);
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_set_inquiry_string);
+#endif
int fsg_common_run_thread(struct fsg_common *common)
{
return 0;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_common_run_thread);
+#endif
+
+struct fsg_common *fsg_common_init(struct fsg_common *common,
+ struct usb_composite_dev *cdev,
+ struct fsg_config *cfg)
+{
+ int rc;
+
+ common = fsg_common_setup(common, !!common);
+ if (IS_ERR(common))
+ return common;
+ common->sysfs = true;
+ common->state = FSG_STATE_IDLE;
+
+ rc = fsg_common_set_num_buffers(common, cfg->fsg_num_buffers);
+ if (rc) {
+ if (common->free_storage_on_release)
+ kfree(common);
+ return ERR_PTR(rc);
+ }
+
+ fsg_common_set_ops(common, cfg->ops);
+ fsg_common_set_private_data(common, cfg->private_data);
+
+ rc = fsg_common_set_cdev(common, cdev, cfg->can_stall);
+ if (rc)
+ goto error_release;
+
+ rc = fsg_common_set_nluns(common, cfg->nluns);
+ if (rc)
+ goto error_release;
+
+ rc = fsg_common_create_luns(common, cfg);
+ if (rc)
+ goto error_release;
+
+
+ fsg_common_set_inquiry_string(common, cfg->vendor_name,
+ cfg->product_name);
+
+ /* Information */
+ INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+
+ rc = fsg_common_run_thread(common);
+ if (rc)
+ goto error_release;
+
+ return common;
+
+error_release:
+ common->state = FSG_STATE_TERMINATED; /* The thread is dead */
+ /* Call fsg_common_release() directly, ref might be not initialised. */
+ fsg_common_release(&common->ref);
+ return ERR_PTR(rc);
+}
+#ifndef USB_FMS_INCLUDED
+EXPORT_SYMBOL(fsg_common_init);
+#endif
static void fsg_common_release(struct kref *ref)
{
struct usb_ep *ep;
unsigned max_burst;
int ret;
- struct fsg_opts *opts;
+#ifndef USB_FMS_INCLUDED
+ struct fsg_opts *opts;
opts = container_of(f->fi, struct fsg_opts, func_inst);
if (!opts->no_configfs) {
ret = fsg_common_set_cdev(fsg->common, c->cdev,
if (ret)
return ret;
}
+#endif
fsg->gadget = gadget;
/****************************** ALLOCATE FUNCTION *************************/
+#ifdef USB_FMS_INCLUDED
+
+static void old_fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+ struct fsg_dev *fsg = fsg_from_func(f);
+ struct fsg_common *common = fsg->common;
+
+ DBG(fsg, "unbind\n");
+ if (fsg->common->fsg == fsg) {
+ fsg->common->new_fsg = NULL;
+ raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+ /* FIXME: make interruptible or killable somehow? */
+ wait_event(common->fsg_wait, common->fsg != fsg);
+ }
+
+ fsg_common_put(common);
+ usb_free_all_descriptors(&fsg->function);
+ kfree(fsg);
+}
+
+static int fsg_bind_config(struct usb_composite_dev *cdev,
+ struct usb_configuration *c,
+ struct fsg_common *common)
+{
+ struct fsg_dev *fsg;
+ int rc;
+
+ fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
+ if (unlikely(!fsg))
+ return -ENOMEM;
+
+ fsg->function.name = FSG_DRIVER_DESC;
+ fsg->function.bind = fsg_bind;
+ fsg->function.unbind = old_fsg_unbind;
+ fsg->function.setup = fsg_setup;
+ fsg->function.set_alt = fsg_set_alt;
+ fsg->function.disable = fsg_disable;
+
+ fsg->common = common;
+ /*
+ * Our caller holds a reference to common structure so we
+ * don't have to be worry about it being freed until we return
+ * from this function. So instead of incrementing counter now
+ * and decrement in error recovery we increment it only when
+ * call to usb_add_function() was successful.
+ */
+
+ rc = usb_add_function(c, &fsg->function);
+ if (unlikely(rc))
+ kfree(fsg);
+ else
+ fsg_common_get(fsg->common);
+ return rc;
+}
+
+#else
+
static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
{
return container_of(to_config_group(item), struct fsg_lun_opts, group);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michal Nazarewicz");
+#endif
+
/************************* Module parameters *************************/
cfg->can_stall = params->stall;
cfg->fsg_num_buffers = fsg_num_buffers;
}
+#ifndef USB_FMS_INCLUDED
EXPORT_SYMBOL(fsg_config_from_params);
+#endif
void fsg_common_put(struct fsg_common *common);
+struct fsg_common *fsg_common_init(struct fsg_common *common,
+ struct usb_composite_dev *cdev,
+ struct fsg_config *cfg);
+
void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
const struct fsg_module_parameters *params,
unsigned int fsg_num_buffers);
+static inline struct fsg_common *
+fsg_common_from_params(struct fsg_common *common,
+ struct usb_composite_dev *cdev,
+ const struct fsg_module_parameters *params,
+ unsigned int fsg_num_buffers)
+ __attribute__((unused));
+static inline struct fsg_common *
+fsg_common_from_params(struct fsg_common *common,
+ struct usb_composite_dev *cdev,
+ const struct fsg_module_parameters *params,
+ unsigned int fsg_num_buffers)
+{
+ struct fsg_config cfg;
+ fsg_config_from_params(&cfg, params, fsg_num_buffers);
+ return fsg_common_init(common, cdev, &cfg);
+}
+
#endif /* USB_F_MASS_STORAGE_H */