diff options
| author | Huang Shijie <b32955@freescale.com> | 2011-10-26 17:31:25 +0800 |
|---|---|---|
| committer | Nitin Garg <nitin.garg@nxp.com> | 2016-01-14 11:00:13 -0600 |
| commit | fab5e75fc45970b89e38db772395c86b73e7100b (patch) | |
| tree | 4783147b0211750fd616c305ff945ec65cc8f70f /drivers/usb | |
| parent | 3a6e5d3037013c99006bde7c8b9dc392452006c8 (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.c | 23 |
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__, |
