Commit fdc01cc2 authored by Krzysztof Opasiak's avatar Krzysztof Opasiak Committed by Felipe Balbi

usb: gadget: printer: Remove pnp_string static buffer

pnp string is usually much shorter than 1k so let's stop wasting 1k of
memory for its buffer and make it dynamically alocated.
This also removes 1k len limitation for pnp_string and
adds a new line after string content if required.
Signed-off-by: default avatarKrzysztof Opasiak <k.opasiak@samsung.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 00b6c62e
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include "u_printer.h" #include "u_printer.h"
#define PNP_STRING_LEN 1024
#define PRINTER_MINORS 4 #define PRINTER_MINORS 4
#define GET_DEVICE_ID 0 #define GET_DEVICE_ID 0
#define GET_PORT_STATUS 1 #define GET_PORT_STATUS 1
...@@ -907,8 +906,7 @@ static bool gprinter_req_match(struct usb_function *f, ...@@ -907,8 +906,7 @@ static bool gprinter_req_match(struct usb_function *f,
switch (ctrl->bRequest) { switch (ctrl->bRequest) {
case GET_DEVICE_ID: case GET_DEVICE_ID:
w_index >>= 8; w_index >>= 8;
if (w_length <= PNP_STRING_LEN && if (USB_DIR_IN & ctrl->bRequestType)
(USB_DIR_IN & ctrl->bRequestType))
break; break;
return false; return false;
case GET_PORT_STATUS: case GET_PORT_STATUS:
...@@ -937,6 +935,7 @@ static int printer_func_setup(struct usb_function *f, ...@@ -937,6 +935,7 @@ static int printer_func_setup(struct usb_function *f,
struct printer_dev *dev = func_to_printer(f); struct printer_dev *dev = func_to_printer(f);
struct usb_composite_dev *cdev = f->config->cdev; struct usb_composite_dev *cdev = f->config->cdev;
struct usb_request *req = cdev->req; struct usb_request *req = cdev->req;
u8 *buf = req->buf;
int value = -EOPNOTSUPP; int value = -EOPNOTSUPP;
u16 wIndex = le16_to_cpu(ctrl->wIndex); u16 wIndex = le16_to_cpu(ctrl->wIndex);
u16 wValue = le16_to_cpu(ctrl->wValue); u16 wValue = le16_to_cpu(ctrl->wValue);
...@@ -953,10 +952,16 @@ static int printer_func_setup(struct usb_function *f, ...@@ -953,10 +952,16 @@ static int printer_func_setup(struct usb_function *f,
if ((wIndex>>8) != dev->interface) if ((wIndex>>8) != dev->interface)
break; break;
value = (dev->pnp_string[0] << 8) | dev->pnp_string[1]; if (!dev->pnp_string) {
memcpy(req->buf, dev->pnp_string, value); value = 0;
break;
}
value = strlen(dev->pnp_string);
buf[0] = (value >> 8) & 0xFF;
buf[1] = value & 0xFF;
memcpy(buf + 2, dev->pnp_string, value);
DBG(dev, "1284 PNP String: %x %s\n", value, DBG(dev, "1284 PNP String: %x %s\n", value,
&dev->pnp_string[2]); dev->pnp_string);
break; break;
case GET_PORT_STATUS: /* Get Port Status */ case GET_PORT_STATUS: /* Get Port Status */
...@@ -964,7 +969,7 @@ static int printer_func_setup(struct usb_function *f, ...@@ -964,7 +969,7 @@ static int printer_func_setup(struct usb_function *f,
if (wIndex != dev->interface) if (wIndex != dev->interface)
break; break;
*(u8 *)req->buf = dev->printer_status; buf[0] = dev->printer_status;
value = min_t(u16, wLength, 1); value = min_t(u16, wLength, 1);
break; break;
...@@ -1157,10 +1162,21 @@ static ssize_t f_printer_opts_pnp_string_show(struct config_item *item, ...@@ -1157,10 +1162,21 @@ static ssize_t f_printer_opts_pnp_string_show(struct config_item *item,
char *page) char *page)
{ {
struct f_printer_opts *opts = to_f_printer_opts(item); struct f_printer_opts *opts = to_f_printer_opts(item);
int result; int result = 0;
mutex_lock(&opts->lock); mutex_lock(&opts->lock);
result = strlcpy(page, opts->pnp_string + 2, PNP_STRING_LEN - 2); if (!opts->pnp_string)
goto unlock;
result = strlcpy(page, opts->pnp_string, PAGE_SIZE);
if (result >= PAGE_SIZE) {
result = PAGE_SIZE;
} else if (page[result - 1] != '\n' && result + 1 < PAGE_SIZE) {
page[result++] = '\n';
page[result] = '\0';
}
unlock:
mutex_unlock(&opts->lock); mutex_unlock(&opts->lock);
return result; return result;
...@@ -1170,13 +1186,24 @@ static ssize_t f_printer_opts_pnp_string_store(struct config_item *item, ...@@ -1170,13 +1186,24 @@ static ssize_t f_printer_opts_pnp_string_store(struct config_item *item,
const char *page, size_t len) const char *page, size_t len)
{ {
struct f_printer_opts *opts = to_f_printer_opts(item); struct f_printer_opts *opts = to_f_printer_opts(item);
int result, l; char *new_pnp;
int result;
mutex_lock(&opts->lock); mutex_lock(&opts->lock);
result = strlcpy(opts->pnp_string + 2, page, PNP_STRING_LEN - 2);
l = strlen(opts->pnp_string + 2) + 2; new_pnp = kstrndup(page, len, GFP_KERNEL);
opts->pnp_string[0] = (l >> 8) & 0xFF; if (!new_pnp) {
opts->pnp_string[1] = l & 0xFF; result = -ENOMEM;
goto unlock;
}
if (opts->pnp_string_allocated)
kfree(opts->pnp_string);
opts->pnp_string_allocated = true;
opts->pnp_string = new_pnp;
result = len;
unlock:
mutex_unlock(&opts->lock); mutex_unlock(&opts->lock);
return result; return result;
...@@ -1270,6 +1297,8 @@ static void gprinter_free_inst(struct usb_function_instance *f) ...@@ -1270,6 +1297,8 @@ static void gprinter_free_inst(struct usb_function_instance *f)
mutex_unlock(&printer_ida_lock); mutex_unlock(&printer_ida_lock);
if (opts->pnp_string_allocated)
kfree(opts->pnp_string);
kfree(opts); kfree(opts);
} }
......
...@@ -18,12 +18,11 @@ ...@@ -18,12 +18,11 @@
#include <linux/usb/composite.h> #include <linux/usb/composite.h>
#define PNP_STRING_LEN 1024
struct f_printer_opts { struct f_printer_opts {
struct usb_function_instance func_inst; struct usb_function_instance func_inst;
int minor; int minor;
char pnp_string[PNP_STRING_LEN]; char *pnp_string;
bool pnp_string_allocated;
unsigned q_len; unsigned q_len;
/* /*
......
...@@ -88,8 +88,8 @@ static const struct usb_descriptor_header *otg_desc[2]; ...@@ -88,8 +88,8 @@ static const struct usb_descriptor_header *otg_desc[2];
static char product_desc [40] = DRIVER_DESC; static char product_desc [40] = DRIVER_DESC;
static char serial_num [40] = "1"; static char serial_num [40] = "1";
static char pnp_string[PNP_STRING_LEN] = static char *pnp_string =
"XXMFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;"; "MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;";
/* static strings, in UTF-8 */ /* static strings, in UTF-8 */
static struct usb_string strings [] = { static struct usb_string strings [] = {
...@@ -143,23 +143,29 @@ static int printer_do_config(struct usb_configuration *c) ...@@ -143,23 +143,29 @@ static int printer_do_config(struct usb_configuration *c)
static int printer_bind(struct usb_composite_dev *cdev) static int printer_bind(struct usb_composite_dev *cdev)
{ {
struct f_printer_opts *opts; struct f_printer_opts *opts;
int ret, len; int ret;
fi_printer = usb_get_function_instance("printer"); fi_printer = usb_get_function_instance("printer");
if (IS_ERR(fi_printer)) if (IS_ERR(fi_printer))
return PTR_ERR(fi_printer); return PTR_ERR(fi_printer);
if (iPNPstring)
strlcpy(&pnp_string[2], iPNPstring, PNP_STRING_LEN - 2);
len = strlen(pnp_string);
pnp_string[0] = (len >> 8) & 0xFF;
pnp_string[1] = len & 0xFF;
opts = container_of(fi_printer, struct f_printer_opts, func_inst); opts = container_of(fi_printer, struct f_printer_opts, func_inst);
opts->minor = 0; opts->minor = 0;
memcpy(opts->pnp_string, pnp_string, PNP_STRING_LEN);
opts->q_len = QLEN; opts->q_len = QLEN;
if (iPNPstring) {
opts->pnp_string = kstrdup(iPNPstring, GFP_KERNEL);
if (!opts->pnp_string) {
ret = -ENOMEM;
goto fail_put_func_inst;
}
opts->pnp_string_allocated = true;
/*
* we don't free this memory in case of error
* as printer cleanup func will do this for us
*/
} else {
opts->pnp_string = pnp_string;
}
ret = usb_string_ids_tab(cdev, strings); ret = usb_string_ids_tab(cdev, strings);
if (ret < 0) if (ret < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment