/* Returns negative errno on error, or zero on success.  */
int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
/* Returns negative errno on error, or zero on success.  */
int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
{
    int size = len*sizeof(u16);
    if (cmap->len != len) {
	fb_dealloc_cmap(cmap);
	if (!len)
	    return 0;
	if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
	    goto fail;
	if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
	    goto fail;
	if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
	    goto fail;
	if (transp) {
	    if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
		goto fail;
	} else
	    cmap->transp = NULL;
    }
    cmap->start = 0;
    cmap->len = len;
    fb_copy_cmap(fb_default_cmap(len), cmap);
    return 0;
fail:
    fb_dealloc_cmap(cmap);
    return -ENOMEM;
}