linux/drivers/usb/gadget/function/f_mass_storage.h

148 lines
4.1 KiB
C
Raw Normal View History

#ifndef USB_F_MASS_STORAGE_H
#define USB_F_MASS_STORAGE_H
#include <linux/usb/composite.h>
#include "storage_common.h"
struct fsg_module_parameters {
char *file[FSG_MAX_LUNS];
bool ro[FSG_MAX_LUNS];
bool removable[FSG_MAX_LUNS];
bool cdrom[FSG_MAX_LUNS];
bool nofua[FSG_MAX_LUNS];
unsigned int file_count, ro_count, removable_count, cdrom_count;
unsigned int nofua_count;
unsigned int luns; /* nluns */
bool stall; /* can_stall */
};
#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \
module_param_array_named(prefix ## name, params.name, type, \
&prefix ## params.name ## _count, \
S_IRUGO); \
MODULE_PARM_DESC(prefix ## name, desc)
#define _FSG_MODULE_PARAM(prefix, params, name, type, desc) \
module_param_named(prefix ## name, params.name, type, \
S_IRUGO); \
MODULE_PARM_DESC(prefix ## name, desc)
#define __FSG_MODULE_PARAMETERS(prefix, params) \
_FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp, \
"names of backing files or devices"); \
_FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool, \
"true to force read-only"); \
_FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool, \
"true to simulate removable media"); \
_FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \
"true to simulate CD-ROM instead of disk"); \
_FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \
"true to ignore SCSI WRITE(10,12) FUA bit"); \
_FSG_MODULE_PARAM(prefix, params, luns, uint, \
"number of LUNs"); \
_FSG_MODULE_PARAM(prefix, params, stall, bool, \
"false to prevent bulk stalls")
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
#define FSG_MODULE_PARAMETERS(prefix, params) \
__FSG_MODULE_PARAMETERS(prefix, params); \
module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
#else
#define FSG_MODULE_PARAMETERS(prefix, params) \
__FSG_MODULE_PARAMETERS(prefix, params)
#endif
struct fsg_common;
/* FSF callback functions */
struct fsg_lun_opts {
struct config_group group;
struct fsg_lun *lun;
int lun_id;
};
struct fsg_opts {
struct fsg_common *common;
struct usb_function_instance func_inst;
struct fsg_lun_opts lun0;
struct config_group *default_groups[2];
bool no_configfs; /* for legacy gadgets */
/*
* Read/write access to configfs attributes is handled by configfs.
*
* This is to protect the data from concurrent access by read/write
* and create symlink/remove symlink.
*/
struct mutex lock;
int refcnt;
};
struct fsg_lun_config {
const char *filename;
char ro;
char removable;
char cdrom;
char nofua;
char inquiry_string[INQUIRY_STRING_LEN];
};
struct fsg_config {
unsigned nluns;
struct fsg_lun_config luns[FSG_MAX_LUNS];
/* Callback functions. */
const struct fsg_operations *ops;
/* Gadget's private data. */
void *private_data;
const char *vendor_name; /* 8 characters or less */
const char *product_name; /* 16 characters or less */
char can_stall;
unsigned int fsg_num_buffers;
};
static inline struct fsg_opts *
fsg_opts_from_func_inst(const struct usb_function_instance *fi)
{
return container_of(fi, struct fsg_opts, func_inst);
}
void fsg_common_get(struct fsg_common *common);
void fsg_common_put(struct fsg_common *common);
void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
void fsg_common_free_buffers(struct fsg_common *common);
int fsg_common_set_cdev(struct fsg_common *common,
struct usb_composite_dev *cdev, bool can_stall);
usb: gadget: mass_storage: Fix freeing luns sysfs implementation Use device_is_registered() instad of sysfs flag to determine if we should free sysfs representation of particular LUN. sysfs flag in fsg common determines if luns attributes should be exposed using sysfs. This flag is used when creating and freeing luns. Unfortunately there is no guarantee that this flag will not be changed between creation and removal of particular LUN. Especially because of lun.0 which is created during allocating instance of function. This may lead to resource leak or NULL pointer dereference: [ 62.539925] Unable to handle kernel NULL pointer dereference at virtual address 00000044 [ 62.548014] pgd = ec994000 [ 62.550679] [00000044] *pgd=6d7be831, *pte=00000000, *ppte=00000000 [ 62.556933] Internal error: Oops: 17 [#1] PREEMPT SMP ARM [ 62.562310] Modules linked in: g_mass_storage(+) [ 62.566916] CPU: 2 PID: 613 Comm: insmod Not tainted 4.2.0-rc4-00077-ge29ee91-dirty #125 [ 62.574984] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 62.581061] task: eca56e80 ti: eca76000 task.ti: eca76000 [ 62.586450] PC is at kernfs_find_ns+0x8/0xe8 [ 62.590698] LR is at kernfs_find_and_get_ns+0x30/0x48 [ 62.595732] pc : [<c01277c0>] lr : [<c0127b88>] psr: 40010053 [ 62.595732] sp : eca77c40 ip : eca77c38 fp : 000008c1 [ 62.607187] r10: 00000001 r9 : c0082f38 r8 : ed41ce40 [ 62.612395] r7 : c05c1484 r6 : 00000000 r5 : 00000000 r4 : c0814488 [ 62.618904] r3 : 00000000 r2 : 00000000 r1 : c05c1484 r0 : 00000000 [ 62.625417] Flags: nZcv IRQs on FIQs off Mode SVC_32 ISA ARM Segment user [ 62.632620] Control: 10c5387d Table: 6c99404a DAC: 00000015 [ 62.638348] Process insmod (pid: 613, stack limit = 0xeca76210) [ 62.644251] Stack: (0xeca77c40 to 0xeca78000) [ 62.648594] 7c40: c0814488 00000000 00000000 c05c1484 ed41ce40 c0127b88 00000000 c0824888 [ 62.656753] 7c60: ed41d038 ed41d030 ed41d000 c012af4c 00000000 c0824858 ed41d038 c02e3314 [ 62.664912] 7c80: ed41d030 00000000 ed41ce04 c02d9e8c c070eda8 eca77cb4 000008c1 c058317c [ 62.673071] 7ca0: 000008c1 ed41d030 ed41ce00 ed41ce04 ed41d000 c02da044 ed41cf48 c0375870 [ 62.681230] 7cc0: ed9d3c04 ed9d3c00 ed52df80 bf000940 fffffff0 c03758f4 c03758c0 00000000 [ 62.689389] 7ce0: bf000564 c03614e0 ed9d3c04 bf000194 c0082f38 00000001 00000000 c0000100 [ 62.697548] 7d00: c0814488 c0814488 c086b1dc c05893a8 00000000 ed7e8320 00000000 c0128b88 [ 62.705707] 7d20: ed8a6b40 00000000 00000000 ed410500 ed8a6b40 c0594818 ed7e8320 00000000 [ 62.713867] 7d40: 00000000 c0129f20 00000000 c082c444 ed8a6b40 c012a684 00001000 00000000 [ 62.722026] 7d60: c0594818 c082c444 00000000 00000000 ed52df80 ed52df80 00000000 00000000 [ 62.730185] 7d80: 00000000 00000000 00000001 00000002 ed8e9b70 ed52df80 bf0006d0 00000000 [ 62.738345] 7da0: ed8e9b70 ed410500 ed618340 c036129c ed8c1c00 bf0006d0 c080b158 ed8c1c00 [ 62.746504] 7dc0: bf0006d0 c080b158 ed8c1c08 ed410500 c0082f38 ed618340 000008c1 c03640ac [ 62.754663] 7de0: 00000000 bf0006d0 c082c8dc c080b158 c080b158 c03642d4 00000000 bf003000 [ 62.762822] 7e00: 00000000 c0009784 00000000 00000001 00000000 c05849b0 00000002 ee7ab780 [ 62.770981] 7e20: 00000002 ed4105c0 0000c53e 000000d0 c0808600 eca77e5c 00000004 00000000 [ 62.779140] 7e40: bf000000 c0095680 c08075a0 ee001f00 ed4105c0 c00cadc0 ed52df80 bf000780 [ 62.787300] 7e60: ed4105c0 bf000780 00000001 bf0007c8 c0082f38 ed618340 000008c1 c0083e24 [ 62.795459] 7e80: 00000001 bf000780 00000001 eca77f58 00000001 bf000780 00000001 c00857f4 [ 62.803618] 7ea0: bf00078c 00007fff 00000000 c00835b4 eca77f58 00000000 c0082fac eca77f58 [ 62.811777] 7ec0: f05038c0 0003b008 bf000904 00000000 00000000 bf00078c 6e72656b 00006c65 [ 62.819936] 7ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 62.828095] 7f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 62.836255] 7f20: 00000000 00000000 00000000 00000000 00000000 00000000 00000003 0003b008 [ 62.844414] 7f40: 0000017b c000f5c8 eca76000 00000000 0003b008 c0085df8 f04ef000 0001b8a9 [ 62.852573] 7f60: f0503258 f05030c2 f0509fe8 00000968 00000dc8 00000000 00000000 00000000 [ 62.860732] 7f80: 00000029 0000002a 00000011 00000000 0000000a 00000000 33f6eb00 0003b008 [ 62.868892] 7fa0: bef01cac c000f400 33f6eb00 0003b008 00000003 0003b008 00000000 00000003 [ 62.877051] 7fc0: 33f6eb00 0003b008 bef01cac 0000017b 00000000 0003b008 0000000b 0003b008 [ 62.885210] 7fe0: bef01ae0 bef01ad0 0001dc23 b6e8c162 800b0070 00000003 c0c0c0c0 c0c0c0c0 [ 62.893380] [<c01277c0>] (kernfs_find_ns) from [<c0824888>] (pm_qos_latency_tolerance_attr_group+0x0/0x10) [ 62.903005] Code: e28dd00c e8bd80f0 e92d41f0 e2923000 (e1d0e4b4) [ 62.909115] ---[ end trace 02fb4373ef095c7b ]--- Acked-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-07-31 19:37:45 +08:00
void fsg_common_remove_lun(struct fsg_lun *lun);
void fsg_common_remove_luns(struct fsg_common *common);
int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
unsigned int id, const char *name,
const char **name_pfx);
int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
const char *pn);
void fsg_config_from_params(struct fsg_config *cfg,
const struct fsg_module_parameters *params,
unsigned int fsg_num_buffers);
#endif /* USB_F_MASS_STORAGE_H */