aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbcmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbcmap.c')
-rw-r--r--drivers/video/fbcmap.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index a79b9762901e..affdf3e32cf3 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -88,26 +88,27 @@ static const struct fb_cmap default_16_colors = {
88 * 88 *
89 */ 89 */
90 90
91int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) 91int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags)
92{ 92{
93 int size = len * sizeof(u16); 93 int size = len * sizeof(u16);
94 int ret = -ENOMEM;
94 95
95 if (cmap->len != len) { 96 if (cmap->len != len) {
96 fb_dealloc_cmap(cmap); 97 fb_dealloc_cmap(cmap);
97 if (!len) 98 if (!len)
98 return 0; 99 return 0;
99 100
100 cmap->red = kmalloc(size, GFP_ATOMIC); 101 cmap->red = kmalloc(size, flags);
101 if (!cmap->red) 102 if (!cmap->red)
102 goto fail; 103 goto fail;
103 cmap->green = kmalloc(size, GFP_ATOMIC); 104 cmap->green = kmalloc(size, flags);
104 if (!cmap->green) 105 if (!cmap->green)
105 goto fail; 106 goto fail;
106 cmap->blue = kmalloc(size, GFP_ATOMIC); 107 cmap->blue = kmalloc(size, flags);
107 if (!cmap->blue) 108 if (!cmap->blue)
108 goto fail; 109 goto fail;
109 if (transp) { 110 if (transp) {
110 cmap->transp = kmalloc(size, GFP_ATOMIC); 111 cmap->transp = kmalloc(size, flags);
111 if (!cmap->transp) 112 if (!cmap->transp)
112 goto fail; 113 goto fail;
113 } else { 114 } else {
@@ -116,12 +117,19 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
116 } 117 }
117 cmap->start = 0; 118 cmap->start = 0;
118 cmap->len = len; 119 cmap->len = len;
119 fb_copy_cmap(fb_default_cmap(len), cmap); 120 ret = fb_copy_cmap(fb_default_cmap(len), cmap);
121 if (ret)
122 goto fail;
120 return 0; 123 return 0;
121 124
122fail: 125fail:
123 fb_dealloc_cmap(cmap); 126 fb_dealloc_cmap(cmap);
124 return -ENOMEM; 127 return ret;
128}
129
130int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
131{
132 return fb_alloc_cmap_gfp(cmap, len, transp, GFP_ATOMIC);
125} 133}
126 134
127/** 135/**
@@ -256,8 +264,12 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
256 int rc, size = cmap->len * sizeof(u16); 264 int rc, size = cmap->len * sizeof(u16);
257 struct fb_cmap umap; 265 struct fb_cmap umap;
258 266
267 if (size < 0 || size < cmap->len)
268 return -E2BIG;
269
259 memset(&umap, 0, sizeof(struct fb_cmap)); 270 memset(&umap, 0, sizeof(struct fb_cmap));
260 rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); 271 rc = fb_alloc_cmap_gfp(&umap, cmap->len, cmap->transp != NULL,
272 GFP_KERNEL);
261 if (rc) 273 if (rc)
262 return rc; 274 return rc;
263 if (copy_from_user(umap.red, cmap->red, size) || 275 if (copy_from_user(umap.red, cmap->red, size) ||