summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2011-10-26 17:31:25 +0800
committerNitin Garg <nitin.garg@nxp.com>2016-01-14 11:00:13 -0600
commitfab5e75fc45970b89e38db772395c86b73e7100b (patch)
tree4783147b0211750fd616c305ff945ec65cc8f70f /drivers/usb
parent3a6e5d3037013c99006bde7c8b9dc392452006c8 (diff)
MLK-11483-4 UTP : replace kzalloc() with vmalloc()
When allocating large memory, such as 128K, vmalloc() uses single page for the allocation process, while kzalloc() has to consume a continuous pages for the allocation. In low memory case, the kzalloc() may fails. So use the vmalloc() instead. Also add some sanity check for the NULL pointer. Add missed line for ENGR00161643-3 UTP : bugfix Signed-off-by: Huang Shijie <b32955@freescale.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/function/fsl_updater.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/usb/gadget/function/fsl_updater.c b/drivers/usb/gadget/function/fsl_updater.c
index 31e2c074a895..490300371d9d 100644
--- a/drivers/usb/gadget/function/fsl_updater.c
+++ b/drivers/usb/gadget/function/fsl_updater.c
@@ -48,9 +48,10 @@ static struct utp_user_data *utp_user_data_alloc(size_t size)
{
struct utp_user_data *uud;
- uud = kzalloc(size + sizeof(*uud), GFP_KERNEL);
+ uud = vmalloc(size + sizeof(*uud));
if (!uud)
return uud;
+ memset(uud, 0, size + sizeof(*uud));
uud->data.size = size + sizeof(uud->data);
INIT_LIST_HEAD(&uud->link);
return uud;
@@ -61,7 +62,7 @@ static void utp_user_data_free(struct utp_user_data *uud)
mutex_lock(&utp_context.lock);
list_del(&uud->link);
mutex_unlock(&utp_context.lock);
- kfree(uud);
+ vfree(uud);
}
/* Get the number of element for list */
@@ -101,8 +102,10 @@ static ssize_t utp_file_read(struct file *file,
if (size >= size_to_put)
free = !0;
- if (copy_to_user(buf, &uud->data, size_to_put))
+ if (copy_to_user(buf, &uud->data, size_to_put)) {
+ printk(KERN_INFO "[ %s ] copy error\n", __func__);
return -EACCES;
+ }
if (free)
utp_user_data_free(uud);
else {
@@ -131,8 +134,13 @@ static ssize_t utp_file_write(struct file *file, const char __user *buf,
if (size < sizeof(uud->data))
return -EINVAL;
uud = utp_user_data_alloc(size);
- if (copy_from_user(&uud->data, buf, size))
+ if (uud == NULL)
+ return -ENOMEM;
+ if (copy_from_user(&uud->data, buf, size)) {
+ printk(KERN_INFO "[ %s ] copy error!\n", __func__);
+ vfree(uud);
return -EACCES;
+ }
mutex_lock(&utp_context.lock);
list_add_tail(&uud->link, &utp_context.write);
/* Go on EXEC routine process */
@@ -389,6 +397,8 @@ static int utp_exec(struct fsg_dev *fsg,
ctx->counter = 0xFFFF;
uud2r = utp_user_data_alloc(cmdsize + 1);
+ if (!uud2r)
+ return -ENOMEM;
uud2r->data.flags = UTP_FLAG_COMMAND;
uud2r->data.payload = payload;
strncpy(uud2r->data.command, command, cmdsize);
@@ -511,11 +521,12 @@ static int utp_handle_message(struct fsg_dev *fsg,
break;
case UTP_EXEC:
pr_debug("%s: EXEC\n", __func__);
- data = kzalloc(fsg->common->data_size, GFP_KERNEL);
+ data = vmalloc(fsg->common->data_size);
+ memset(data, 0, fsg->common->data_size);
/* copy data from usb buffer to utp buffer */
utp_do_write(fsg, data, fsg->common->data_size);
utp_exec(fsg, data, fsg->common->data_size, param);
- kfree(data);
+ vfree(data);
break;
case UTP_GET: /* data from device to host */
pr_debug("%s: GET, %d bytes\n", __func__,