diff options
-rw-r--r-- | drivers/usb/gadget/function/f_mass_storage.c | 28 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_mass_storage.h | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/function/storage_common.c | 24 | ||||
-rw-r--r-- | drivers/usb/gadget/function/storage_common.h | 10 |
4 files changed, 57 insertions, 6 deletions
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 2505117e88e8..8f3659b65f53 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -311,11 +311,7 @@ struct fsg_common { /* Gadget's private data. */ void *private_data; - /* - * Vendor (8 chars), product (16 chars), release (4 - * hexadecimal digits) and NUL byte - */ - char inquiry_string[8 + 16 + 4 + 1]; + char inquiry_string[INQUIRY_STRING_LEN]; struct kref ref; }; @@ -1107,7 +1103,12 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) buf[5] = 0; /* No special options */ buf[6] = 0; buf[7] = 0; - memcpy(buf + 8, common->inquiry_string, sizeof common->inquiry_string); + if (curlun->inquiry_string[0]) + memcpy(buf + 8, curlun->inquiry_string, + sizeof(curlun->inquiry_string)); + else + memcpy(buf + 8, common->inquiry_string, + sizeof(common->inquiry_string)); return 36; } @@ -3209,12 +3210,27 @@ static ssize_t fsg_lun_opts_nofua_store(struct config_item *item, CONFIGFS_ATTR(fsg_lun_opts_, nofua); +static ssize_t fsg_lun_opts_inquiry_string_show(struct config_item *item, + char *page) +{ + return fsg_show_inquiry_string(to_fsg_lun_opts(item)->lun, page); +} + +static ssize_t fsg_lun_opts_inquiry_string_store(struct config_item *item, + const char *page, size_t len) +{ + return fsg_store_inquiry_string(to_fsg_lun_opts(item)->lun, page, len); +} + +CONFIGFS_ATTR(fsg_lun_opts_, inquiry_string); + static struct configfs_attribute *fsg_lun_attrs[] = { &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, + &fsg_lun_opts_attr_inquiry_string, NULL, }; diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h index b6a9918eaefb..d3902313b8ac 100644 --- a/drivers/usb/gadget/function/f_mass_storage.h +++ b/drivers/usb/gadget/function/f_mass_storage.h @@ -100,6 +100,7 @@ struct fsg_lun_config { char removable; char cdrom; char nofua; + char inquiry_string[INQUIRY_STRING_LEN]; }; struct fsg_config { diff --git a/drivers/usb/gadget/function/storage_common.c b/drivers/usb/gadget/function/storage_common.c index 990df221c629..8fbf6861690d 100644 --- a/drivers/usb/gadget/function/storage_common.c +++ b/drivers/usb/gadget/function/storage_common.c @@ -369,6 +369,12 @@ ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf) } EXPORT_SYMBOL_GPL(fsg_show_removable); +ssize_t fsg_show_inquiry_string(struct fsg_lun *curlun, char *buf) +{ + return sprintf(buf, "%s\n", curlun->inquiry_string); +} +EXPORT_SYMBOL_GPL(fsg_show_inquiry_string); + /* * The caller must hold fsg->filesem for reading when calling this function. */ @@ -499,4 +505,22 @@ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, } EXPORT_SYMBOL_GPL(fsg_store_removable); +ssize_t fsg_store_inquiry_string(struct fsg_lun *curlun, const char *buf, + size_t count) +{ + const size_t len = min(count, sizeof(curlun->inquiry_string)); + + if (len == 0 || buf[0] == '\n') { + curlun->inquiry_string[0] = 0; + } else { + snprintf(curlun->inquiry_string, + sizeof(curlun->inquiry_string), "%-28s", buf); + if (curlun->inquiry_string[len-1] == '\n') + curlun->inquiry_string[len-1] = ' '; + } + + return count; +} +EXPORT_SYMBOL_GPL(fsg_store_inquiry_string); + MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/function/storage_common.h b/drivers/usb/gadget/function/storage_common.h index c3544e61da66..e69848994cb4 100644 --- a/drivers/usb/gadget/function/storage_common.h +++ b/drivers/usb/gadget/function/storage_common.h @@ -88,6 +88,12 @@ do { \ #define ASC(x) ((u8) ((x) >> 8)) #define ASCQ(x) ((u8) (x)) +/* + * Vendor (8 chars), product (16 chars), release (4 hexadecimal digits) and NUL + * byte + */ +#define INQUIRY_STRING_LEN ((size_t) (8 + 16 + 4 + 1)) + struct fsg_lun { struct file *filp; loff_t file_length; @@ -112,6 +118,7 @@ struct fsg_lun { struct device dev; const char *name; /* "lun.name" */ const char **name_pfx; /* "function.name" */ + char inquiry_string[INQUIRY_STRING_LEN]; }; static inline bool fsg_lun_is_open(struct fsg_lun *curlun) @@ -210,6 +217,7 @@ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf); ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf); ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, char *buf); +ssize_t fsg_show_inquiry_string(struct fsg_lun *curlun, char *buf); ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf); ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf); ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, @@ -221,5 +229,7 @@ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, const char *buf, size_t count); ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, size_t count); +ssize_t fsg_store_inquiry_string(struct fsg_lun *curlun, const char *buf, + size_t count); #endif /* USB_STORAGE_COMMON_H */ |