linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Resource management.
@ 2005-02-21 19:11 James Simmons
  2005-02-21 22:53 ` Antonino A. Daplas
  0 siblings, 1 reply; 16+ messages in thread
From: James Simmons @ 2005-02-21 19:11 UTC (permalink / raw)
  To: Antonino A. Daplas; +Cc: Geert Uytterhoeven, Linux Fbdev development list


Hi!

   This is my first run at the resource management code. Comments are 
welcomed :-)

diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/Makefile fbdev-2.6/drivers/video/Makefile
--- linus-2.6/drivers/video/Makefile	2005-02-21 10:38:42.000000000 -0800
+++ fbdev-2.6/drivers/video/Makefile	2005-02-17 14:26:42.000000000 -0800
@@ -8,7 +8,7 @@
 obj-$(CONFIG_LOGO)		  += logo/
 obj-$(CONFIG_SYSFS)		  += backlight/
 
-obj-$(CONFIG_FB)                  += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
+obj-$(CONFIG_FB)                  += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o resmgt.o softcursor.o
 # Only include macmodes.o if we have FB support and are PPC
 ifeq ($(CONFIG_FB),y)
 obj-$(CONFIG_PPC)                 += macmodes.o
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/bitblit.c fbdev-2.6/drivers/video/console/bitblit.c
--- linus-2.6/drivers/video/console/bitblit.c	2005-02-21 10:38:47.000000000 -0800
+++ fbdev-2.6/drivers/video/console/bitblit.c	2005-02-18 10:35:23.000000000 -0800
@@ -114,12 +114,13 @@
 	void (*move_aligned)(struct fb_info *info, struct fb_pixmap *buf,
 			     u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
 			     u32 height);
+	struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	unsigned int width = (vc->vc_font.width + 7) >> 3;
 	unsigned int cellsize = vc->vc_font.height * width;
-	unsigned int maxcnt = info->pixmap.size/cellsize;
-	unsigned int scan_align = info->pixmap.scan_align - 1;
-	unsigned int buf_align = info->pixmap.buf_align - 1;
+	unsigned int maxcnt = pad->size/cellsize;
+	unsigned int scan_align = pad->scan_align - 1;
+	unsigned int buf_align = pad->buf_align - 1;
 	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
 	unsigned int shift_high = 8, pitch, cnt, size, k;
 	unsigned int idx = vc->vc_font.width >> 3;
@@ -141,7 +142,7 @@
 	image.height = vc->vc_font.height;
 	image.depth = 1;
 
-	if (info->pixmap.outbuf && info->pixmap.inbuf) {
+	if (pad->outbuf && pad->inbuf) {
 		move_aligned = fb_iomove_buf_aligned;
 		move_unaligned = fb_iomove_buf_unaligned;
 	} else {
@@ -159,7 +160,7 @@
 		pitch &= ~scan_align;
 		size = pitch * image.height + buf_align;
 		size &= ~buf_align;
-		dst = fb_get_buffer_offset(info, &info->pixmap, size);
+		dst = fb_get_buffer_offset(info, pad, size);
 		image.data = dst;
 		if (mod) {
 			while (k--) {
@@ -171,9 +172,9 @@
 					src = buf;
 				}
 
-				move_unaligned(info, &info->pixmap, dst, pitch,
-					       src, idx, image.height,
-					       shift_high, shift_low, mod);
+				move_unaligned(info, pad, dst, pitch, src, idx,
+						image.height, shift_high, shift_low,
+						mod);
 				shift_low += mod;
 				dst += (shift_low >= 8) ? width : width - 1;
 				shift_low &= 7;
@@ -189,8 +190,7 @@
 					src = buf;
 				}
 
-				move_aligned(info, &info->pixmap, dst, pitch,
-					     src, idx, image.height);
+				move_aligned(info, pad, dst, pitch, src, idx, image.height);
 				dst += width;
 			}
 		}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/tileblit.c fbdev-2.6/drivers/video/console/tileblit.c
--- linus-2.6/drivers/video/console/tileblit.c	2005-02-21 10:38:47.000000000 -0800
+++ fbdev-2.6/drivers/video/console/tileblit.c	2005-02-18 10:35:42.000000000 -0800
@@ -56,9 +56,10 @@
 		       const unsigned short *s, int count, int yy, int xx,
 		       int fg, int bg)
 {
-	struct fb_tileblit blit;
+	struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int size = sizeof(u32) * count, i;
+	struct fb_tileblit blit;
 
 	blit.sx = xx;
 	blit.sy = yy;
@@ -67,7 +68,7 @@
 	blit.fg = fg;
 	blit.bg = bg;
 	blit.length = count;
-	blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size);
+	blit.indices = (u32 *) fb_get_buffer_offset(info, pad, size);
 	for (i = 0; i < count; i++)
 		blit.indices[i] = (u32)(scr_readw(s++) & charmask);
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmem.c fbdev-2.6/drivers/video/fbmem.c
--- linus-2.6/drivers/video/fbmem.c	2005-01-24 09:43:47.000000000 -0800
+++ fbdev-2.6/drivers/video/fbmem.c	2005-02-21 10:31:38.000000000 -0800
@@ -52,8 +52,6 @@
      *  Frame buffer device initialization and setup routines
      */
 
-#define FBPIXMAPSIZE	(1024 * 8)
-
 static struct notifier_block *fb_notifier_list;
 struct fb_info *registered_fb[FB_MAX];
 int num_registered_fb;
@@ -77,134 +75,6 @@
 }
 EXPORT_SYMBOL(fb_get_color_depth);
 
-/*
- * Drawing helpers.
- */
-void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
-			   u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-			   u32 height)
-{
-	int i;
-
-	for (i = height; i--; ) {
-		buf->outbuf(info, dst, src, s_pitch);
-		src += s_pitch;
-		dst += d_pitch;
-	}
-}
-
-void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
-			    u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-			    u32 height)
-{
-	int i, j;
-
-	for (i = height; i--; ) {
-		for (j = 0; j < s_pitch; j++)
-			dst[j] = src[j];
-		src += s_pitch;
-		dst += d_pitch;
-	}
-}
-
-void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
-			     u8 *dst, u32 d_pitch, u8 *src, u32 idx,
-			     u32 height, u32 shift_high, u32 shift_low,
-			     u32 mod)
-{
-	u8 mask = (u8) (0xfff << shift_high), tmp;
-	int i, j;
-
-	for (i = height; i--; ) {
-		for (j = 0; j < idx; j++) {
-			tmp = buf->inbuf(info, dst+j);
-			tmp &= mask;
-			tmp |= *src >> shift_low;
-			buf->outbuf(info, dst+j, &tmp, 1);
-			tmp = *src << shift_high;
-			buf->outbuf(info, dst+j+1, &tmp, 1);
-			src++;
-		}
-		tmp = buf->inbuf(info, dst+idx);
-		tmp &= mask;
-		tmp |= *src >> shift_low;
-		buf->outbuf(info, dst+idx, &tmp, 1);
-		if (shift_high < mod) {
-			tmp = *src << shift_high;
-			buf->outbuf(info, dst+idx+1, &tmp, 1);
-		}	
-		src++;
-		dst += d_pitch;
-	}
-}
-
-void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
-			      u8 *dst, u32 d_pitch, u8 *src, u32 idx,
-			      u32 height, u32 shift_high, u32 shift_low,
-			      u32 mod)
-{
-	u8 mask = (u8) (0xfff << shift_high), tmp;
-	int i, j;
-
-	for (i = height; i--; ) {
-		for (j = 0; j < idx; j++) {
-			tmp = dst[j];
-			tmp &= mask;
-			tmp |= *src >> shift_low;
-			dst[j] = tmp;
-			tmp = *src << shift_high;
-			dst[j+1] = tmp;
-			src++;
-		}
-		tmp = dst[idx];
-		tmp &= mask;
-		tmp |= *src >> shift_low;
-		dst[idx] = tmp;
-		if (shift_high < mod) {
-			tmp = *src << shift_high;
-			dst[idx+1] = tmp;
-		}
-		src++;
-		dst += d_pitch;
-	}
-}
-
-/*
- * we need to lock this section since fb_cursor
- * may use fb_imageblit()
- */
-char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
-{
-	u32 align = buf->buf_align - 1, offset;
-	char *addr = buf->addr;
-
-	/* If IO mapped, we need to sync before access, no sharing of
-	 * the pixmap is done
-	 */
-	if (buf->flags & FB_PIXMAP_IO) {
-		if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
-			info->fbops->fb_sync(info);
-		return addr;
-	}
-
-	/* See if we fit in the remaining pixmap space */
-	offset = buf->offset + align;
-	offset &= ~align;
-	if (offset + size > buf->size) {
-		/* We do not fit. In order to be able to re-use the buffer,
-		 * we must ensure no asynchronous DMA'ing or whatever operation
-		 * is in progress, we sync for that.
-		 */
-		if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
-			info->fbops->fb_sync(info);
-		offset = 0;
-	}
-	buf->offset = offset + size;
-	addr += offset;
-
-	return addr;
-}
-
 #ifdef CONFIG_LOGO
 #include <linux/linux_logo.h>
 
@@ -1075,18 +945,8 @@
 		/* Not fatal */
 		printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(c));
 	}
-	
-	if (fb_info->pixmap.addr == NULL) {
-		fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
-		if (fb_info->pixmap.addr) {
-			fb_info->pixmap.size = FBPIXMAPSIZE;
-			fb_info->pixmap.buf_align = 1;
-			fb_info->pixmap.scan_align = 1;
-			fb_info->pixmap.access_align = 4;
-			fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
-		}
-	}	
-	fb_info->pixmap.offset = 0;
+
+	fb_init_resources(fb_info);
 
 	if (!fb_info->modelist.prev ||
 	    !fb_info->modelist.next ||
@@ -1128,9 +988,7 @@
 	if (!registered_fb[i])
 		return -EINVAL;
 	devfs_remove("fb/%d", i);
-
-	if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
-		kfree(fb_info->pixmap.addr);
+	fb_release_resources(&fb_info->resources);
 	fb_destroy_modelist(&fb_info->modelist);
 	registered_fb[i]=NULL;
 	num_registered_fb--;
@@ -1308,11 +1166,6 @@
 EXPORT_SYMBOL(fb_set_var);
 EXPORT_SYMBOL(fb_blank);
 EXPORT_SYMBOL(fb_pan_display);
-EXPORT_SYMBOL(fb_get_buffer_offset);
-EXPORT_SYMBOL(fb_iomove_buf_unaligned);
-EXPORT_SYMBOL(fb_iomove_buf_aligned);
-EXPORT_SYMBOL(fb_sysmove_buf_unaligned);
-EXPORT_SYMBOL(fb_sysmove_buf_aligned);
 EXPORT_SYMBOL(fb_set_suspend);
 EXPORT_SYMBOL(fb_register_client);
 EXPORT_SYMBOL(fb_unregister_client);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/neofb.c fbdev-2.6/drivers/video/neofb.c
--- linus-2.6/drivers/video/neofb.c	2005-02-21 10:38:44.000000000 -0800
+++ fbdev-2.6/drivers/video/neofb.c	2005-02-18 14:55:58.000000000 -0800
@@ -1472,10 +1472,11 @@
 static void
 neo2200_imageblit(struct fb_info *info, const struct fb_image *image)
 {
+	struct fb_pixmap *pad = fb_find_resource("drawable", &info->resources);
 	struct neofb_par *par = (struct neofb_par *) info->par;
 	int s_pitch = (image->width * image->depth + 7) >> 3;
-	int scan_align = info->pixmap.scan_align - 1;
-	int buf_align = info->pixmap.buf_align - 1;
+	int scan_align = pad->scan_align - 1;
+	int buf_align = pad->buf_align - 1;
 	int bltCntl_flags, d_pitch, data_len;
 
 	// The data is padded for the hardware
@@ -1728,8 +1729,6 @@
 static int __devinit neo_map_video(struct fb_info *info,
 				   struct pci_dev *dev, int video_len)
 {
-	//unsigned long addr;
-
 	DBG("neo_map_video");
 
 	info->fix.smem_start = pci_resource_start(dev, 0);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/resmgt.c fbdev-2.6/drivers/video/resmgt.c
--- linus-2.6/drivers/video/resmgt.c	1969-12-31 16:00:00.000000000 -0800
+++ fbdev-2.6/drivers/video/resmgt.c	2005-02-18 12:23:43.000000000 -0800
@@ -0,0 +1,279 @@
+/*
+ *  linux/drivers/video/resmgt.c -- Manages the resources of a graphics card. 
+ *
+ *	Copyright (C) 2005 James Simmons <jsimmons@www.infradead.org>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/fb.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...)	printk("modedb %s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define FBPIXMAPSIZE	(1024 * 8)
+
+/*
+ * Data padding functions.
+ */
+void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
+			    u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
+			    u32 height)
+{
+	int i, j;
+
+	for (i = height; i--; ) {
+		for (j = 0; j < s_pitch; j++)
+			dst[j] = src[j];
+		src += s_pitch;
+		dst += d_pitch;
+	}
+}
+EXPORT_SYMBOL(fb_sysmove_buf_aligned);
+
+void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
+			      u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height,
+			      u32 shift_high, u32 shift_low, u32 mod)
+{
+	u8 mask = (u8) (0xfff << shift_high), tmp;
+	int i, j;
+
+	for (i = height; i--; ) {
+		for (j = 0; j < idx; j++) {
+			tmp = dst[j];
+			tmp &= mask;
+			tmp |= *src >> shift_low;
+			dst[j] = tmp;
+			tmp = *src << shift_high;
+			dst[j+1] = tmp;
+			src++;
+		}
+		tmp = dst[idx];
+		tmp &= mask;
+		tmp |= *src >> shift_low;
+		dst[idx] = tmp;
+		if (shift_high < mod) {
+			tmp = *src << shift_high;
+			dst[idx+1] = tmp;
+		}
+		src++;
+		dst += d_pitch;
+	}
+}
+EXPORT_SYMBOL(fb_sysmove_buf_unaligned);
+
+void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *pad,
+			   u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,		
+			   u32 height)
+{
+	int i;
+
+	for (i = height; i--; ) {
+		pad->outbuf(info, dst, src, s_pitch);
+		src += s_pitch;
+		dst += d_pitch;
+	}
+}
+EXPORT_SYMBOL(fb_iomove_buf_aligned);
+
+void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *pad,
+			     u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height,
+			     u32 shift_high, u32 shift_low, u32 mod)
+{
+	u8 mask = (u8) (0xfff << shift_high), tmp;
+	u8 __iomem *buf;
+	int i, j;
+
+	for (i = height; i--; ) {
+		for (j = 0; j < idx; j++) {
+			buf = pad->inbuf(info, dst+j, 1);
+			tmp = *buf;
+			tmp &= mask;
+			tmp |= *src >> shift_low;
+			pad->outbuf(info, dst+j, &tmp, 1);
+			tmp = *src << shift_high;
+			pad->outbuf(info, dst+j+1, &tmp, 1);
+			src++;
+		}
+		buf = pad->inbuf(info, dst+idx, 1);
+		tmp = *buf;
+		tmp &= mask;
+		tmp |= *src >> shift_low;
+		pad->outbuf(info, dst+idx, &tmp, 1);
+		if (shift_high < mod) {
+			tmp = *src << shift_high;
+			pad->outbuf(info, dst+idx+1, &tmp, 1);
+		}
+		src++;
+		dst += d_pitch;
+	}
+}
+EXPORT_SYMBOL(fb_iomove_buf_unaligned);
+
+/*
+ * we need to lock this section since fb_cursor
+ * may use fb_imageblit()
+ */
+char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
+{
+	u32 align = buf->buf_align - 1, offset;
+	char *addr = buf->addr;
+
+	/* If IO mapped, we need to sync before access, no sharing of
+	 * the pixmap is done
+	 */
+	if (buf->flags & FB_PIXMAP_IO) {
+		if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+			info->fbops->fb_sync(info);
+		return addr;
+	}
+
+	/* See if we fit in the remaining pixmap space */
+	offset = buf->offset + align;
+	offset &= ~align;
+	if (offset + size > buf->size) {
+		/* We do not fit. In order to be able to re-use the buffer,
+		 * we must ensure no asynchronous DMA'ing or whatever operation
+		 * is in progress, we sync for that.
+		 */
+		if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+			info->fbops->fb_sync(info);
+		offset = 0;
+	}
+	buf->offset = offset + size;
+	addr += offset;
+	return addr;
+}
+EXPORT_SYMBOL(fb_get_buffer_offset);
+
+struct graphics_resource {
+	struct fb_pixmap *resource;
+	struct list_head list;
+};
+
+struct fb_pixmap * fb_find_resource(const char *name, struct list_head *head)
+{
+	struct graphics_resource *rlist = NULL;
+	struct fb_pixmap *resource;
+	struct list_head *pos;
+
+	list_for_each(pos, head) {
+		rlist = list_entry(pos, struct graphics_resource, list);
+		resource = rlist->resource;
+		if (!strncmp(resource->name, name, strlen(name)))
+			return rlist->resource;
+	}
+	return NULL;
+}
+
+int fb_add_resource(struct fb_pixmap *res, struct list_head *head)
+{
+	struct fb_pixmap *resource = fb_find_resource(res->name, head);
+	struct graphics_resource *rlist = NULL;
+
+	if (resource)
+		return 1;
+	rlist = kmalloc(sizeof(struct graphics_resource), GFP_KERNEL);
+	if (!rlist)
+		return -ENOMEM;
+	rlist->resource = res;
+	list_add(&rlist->list, head);
+	return 0;
+}
+
+int fb_remove_resource(struct fb_pixmap *resource, struct list_head *head)
+{
+	struct graphics_resource *rlist;
+	struct list_head *pos, *n;
+
+	if (!resource)
+		return 0;
+
+	list_for_each_safe(pos, n, head) {
+		rlist = list_entry(pos, struct graphics_resource, list);
+		if (!strncmp(resource->name, rlist->resource->name, strlen(rlist->resource->name))) {
+			if (rlist->resource->addr && (rlist->resource->flags & FB_PIXMAP_DEFAULT))
+				kfree(rlist->resource->addr);
+			kfree(rlist->resource);
+			list_del(pos);
+			kfree(pos);
+		}
+	}
+	return 0;
+}
+
+int fb_init_resources(struct fb_info *info)
+{
+	int size = sizeof(struct fb_pixmap) + FBPIXMAPSIZE;
+	struct fb_pixmap *pad, *buf;
+	char *p;
+
+	if (!info->resources.prev || !info->resources.next ||
+	    list_empty(&info->resources))
+		INIT_LIST_HEAD(&info->resources);
+
+	// First we create our drawing pad
+	pad = fb_find_resource("scratchpad", &info->resources);
+	if (!pad) {
+		// Next we create our scratch pad.
+		p = kmalloc(size, GFP_KERNEL);
+		if (!p)
+			return -ENOMEM;
+		memset(p, 0, size);
+		
+		pad = (struct fb_pixmap *) p;
+		pad->addr = p + sizeof(struct fb_pixmap);
+		strcpy(pad->name, "scratchpad");
+		pad->size = FBPIXMAPSIZE;
+		pad->buf_align = 1;
+		pad->scan_align = 1;
+		pad->access_align = 4;
+		pad->flags = FB_PIXMAP_DEFAULT;
+		pad->offset = 0;
+		fb_add_resource(pad, &info->resources);
+	}
+	// Now we create the framebuffer drawable surface
+	p = kmalloc(sizeof(struct fb_pixmap), GFP_KERNEL);
+	if (!p) {
+		fb_remove_resource(pad, &info->resources);
+		return -ENOMEM;
+	}
+	memset(p, 0, sizeof(struct fb_pixmap));
+	buf = (struct fb_pixmap *) p;
+	strcpy(buf->name, "drawable");
+	buf->addr = info->screen_base;
+	if (info->screen_size)
+		buf->size = info->screen_size;
+	else
+		buf->size = info->fix.smem_len;
+	buf->buf_align = pad->buf_align;
+	buf->scan_align = pad->scan_align;
+	buf->access_align = pad->access_align;
+	buf->flags = FB_PIXMAP_IO;
+	buf->offset = 0;
+	fb_add_resource(buf, &info->resources);
+	return 0;
+}
+
+void fb_release_resources(struct list_head *head)
+{
+	struct graphics_resource *rlist;
+	struct list_head *pos, *n;
+	
+	list_for_each_safe(pos, n, head) {
+		rlist = list_entry(pos, struct graphics_resource, list);
+		if (rlist->resource->addr && (rlist->resource->flags & FB_PIXMAP_DEFAULT))
+			kfree(rlist->resource->addr);
+		kfree(rlist->resource);
+		list_del(pos);
+		kfree(pos);
+	}
+}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/riva/fbdev.c fbdev-2.6/drivers/video/riva/fbdev.c
--- linus-2.6/drivers/video/riva/fbdev.c	2005-02-21 10:38:49.000000000 -0800
+++ fbdev-2.6/drivers/video/riva/fbdev.c	2005-02-21 09:22:04.000000000 -0800
@@ -1166,6 +1166,7 @@
 
 static int rivafb_set_par(struct fb_info *info)
 {
+	struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
 	struct riva_par *par = (struct riva_par *) info->par;
 
 	NVTRACE_ENTER();
@@ -1182,9 +1183,9 @@
 				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 
 	if (info->flags & FBINFO_HWACCEL_DISABLED)
-		info->pixmap.scan_align = 1;
+		pad->scan_align = 1;
 	else
-		info->pixmap.scan_align = 4;
+		pad->scan_align = 4;
 	NVTRACE_LEAVE();
 	return 0;
 }
@@ -1580,6 +1581,7 @@
  */
 static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
+	struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
 	struct riva_par *par = (struct riva_par *) info->par;
 	u8 data[MAX_CURS * MAX_CURS/8];
 	u16 fg, bg;
@@ -1637,9 +1639,8 @@
 				break;
 			}
 
-			fb_sysmove_buf_aligned(info, &info->pixmap, data,
-					       d_pitch, src, s_pitch,
-					       cursor->image.height);
+			fb_sysmove_buf_aligned(info, pad, data, d_pitch, 
+						src, s_pitch, cursor->image.height);
 
 			bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
 				((info->cmap.green[bg_idx] & 0xf8) << 2) |
@@ -1725,10 +1726,6 @@
 
 	cmap_len = riva_get_cmap_len(&info->var);
 	fb_alloc_cmap(&info->cmap, cmap_len, 0);	
-
-	info->pixmap.size = 8 * 1024;
-	info->pixmap.buf_align = 4;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
 	info->var.yres_virtual = -1;
 	NVTRACE_LEAVE();
 	return (rivafb_check_var(&info->var, info));
@@ -1901,8 +1898,10 @@
 			     	const struct pci_device_id *ent)
 {
 	struct riva_par *default_par;
+	struct fb_pixmap *pad;
 	struct fb_info *info;
-	int ret;
+	int size, ret;
+	char *p;
 
 	NVTRACE_ENTER();
 	assert(pd != NULL);
@@ -1916,12 +1915,25 @@
 	default_par = (struct riva_par *) info->par;
 	default_par->pdev = pd;
 
-	info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
-	if (info->pixmap.addr == NULL) {
+	// We have special needs for writing to the framebuffer.
+	INIT_LIST_HEAD(&info->resources);
+	size = sizeof(struct fb_pixmap) + 1024*8;
+	p = kmalloc(size, GFP_KERNEL);
+	if (!p) {
 	    	ret = -ENOMEM;
 		goto err_framebuffer_release;
 	}
-	memset(info->pixmap.addr, 0, 8 * 1024);
+	memset(p, 0, size);
+	pad = (struct fb_pixmap *) p;
+	pad->addr = p + sizeof(struct fb_pixmap);
+	strcpy(pad->name, "scratchpad");
+	pad->size = 8*1024;
+	pad->buf_align = 4;
+	pad->scan_align = 1;
+	pad->access_align = 4;
+	pad->flags = FB_PIXMAP_DEFAULT;
+	pad->offset = 0;
+	fb_add_resource(pad, &info->resources);
 
 	ret = pci_enable_device(pd);
 	if (ret < 0) {
@@ -2091,7 +2103,7 @@
 err_disable_device:
 	pci_disable_device(pd);
 err_free_pixmap:
-	kfree(info->pixmap.addr);
+	fb_add_resource(pad, &info->resources);
 err_framebuffer_release:
 	framebuffer_release(info);
 err_ret:
@@ -2126,7 +2138,7 @@
 		iounmap(par->riva.PRAMIN);
 	pci_release_regions(pd);
 	pci_disable_device(pd);
-	kfree(info->pixmap.addr);
+	fb_release_resources(&info->resources);
 	framebuffer_release(info);
 	pci_set_drvdata(pd, NULL);
 	NVTRACE_LEAVE();
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/softcursor.c fbdev-2.6/drivers/video/softcursor.c
--- linus-2.6/drivers/video/softcursor.c	2005-02-21 10:38:44.000000000 -0800
+++ fbdev-2.6/drivers/video/softcursor.c	2005-02-18 10:57:01.000000000 -0800
@@ -19,8 +19,9 @@
 
 int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-	unsigned int scan_align = info->pixmap.scan_align - 1;
-	unsigned int buf_align = info->pixmap.buf_align - 1;
+	struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
+	unsigned int scan_align = pad->scan_align - 1;
+	unsigned int buf_align = pad->buf_align - 1;
 	unsigned int i, size, dsize, s_pitch, d_pitch;
 	struct fb_image *image;
 	u8 *dst, *src;
@@ -41,7 +42,7 @@
 
 	size = d_pitch * image->height + buf_align;
 	size &= ~buf_align;
-	dst = fb_get_buffer_offset(info, &info->pixmap, size);
+	dst = fb_get_buffer_offset(info, pad, size);
 
 	if (cursor->enable) {
 		switch (cursor->rop) {
@@ -57,18 +58,16 @@
 		}
 	} else 
 		memcpy(src, image->data, dsize);
-	
-	if (info->pixmap.outbuf)
-		fb_iomove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
+
+	if (pad->outbuf)
+		fb_iomove_buf_aligned(info, pad, dst, d_pitch, src,
 				  s_pitch, image->height);
 	else
-		fb_sysmove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
+		fb_sysmove_buf_aligned(info, pad, dst, d_pitch, src,
 				   s_pitch, image->height);
-
 	image->data = dst;
 	info->fbops->fb_imageblit(info, image);
 	kfree(src);
-
 	return 0;
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/linux/fb.h fbdev-2.6/include/linux/fb.h
--- linus-2.6/include/linux/fb.h	2005-02-21 10:40:46.000000000 -0800
+++ fbdev-2.6/include/linux/fb.h	2005-02-18 12:00:40.000000000 -0800
@@ -514,6 +514,7 @@
 #define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
 
 struct fb_pixmap {
+	char name[16];		/* Name of the resource			*/
 	u8  *addr;		/* pointer to memory			*/
 	u32 size;		/* size of buffer in bytes		*/
 	u32 offset;		/* current offset to buffer		*/
@@ -523,7 +524,7 @@
 	u32 flags;		/* see FB_PIXMAP_*			*/
 	/* access methods */
 	void (*outbuf)(struct fb_info *info, u8 *addr, u8 *src, unsigned int size);
-	u8   (*inbuf) (struct fb_info *info, u8 *addr);
+	u8*  (*inbuf) (struct fb_info *info, u8 *addr, unsigned int size);
 };
 
 
@@ -707,11 +708,10 @@
 	struct fb_var_screeninfo var;	/* Current var */
 	struct fb_fix_screeninfo fix;	/* Current fix */
 	struct fb_monspecs monspecs;	/* Current Monitor specs */
+	struct list_head resources;	/* Graphics resources */
+	struct list_head modelist;      /* mode list */
 	struct work_struct queue;	/* Framebuffer event queue */
-	struct fb_pixmap pixmap;	/* Image hardware mapper */
-	struct fb_pixmap sprite;	/* Cursor hardware mapper */
 	struct fb_cmap cmap;		/* Current cmap */
-	struct list_head modelist;      /* mode list */
 	struct fb_ops *fbops;
 	struct device *device;
 #ifdef CONFIG_FB_TILEBLITTING
@@ -807,6 +807,14 @@
 extern int unregister_framebuffer(struct fb_info *fb_info);
 extern int fb_prepare_logo(struct fb_info *fb_info);
 extern int fb_show_logo(struct fb_info *fb_info);
+extern void fb_set_suspend(struct fb_info *info, int state);
+extern int fb_get_color_depth(struct fb_info *info);
+extern int fb_get_options(char *name, char **option);
+
+extern struct fb_info *registered_fb[FB_MAX];
+extern int num_registered_fb;
+
+/* drivers/video/resmgt.c */
 extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
 extern void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
 				u8 *dst, u32 d_pitch, u8 *src, u32 idx,
@@ -820,12 +828,11 @@
 extern void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
 				u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
 				u32 height);
-extern void fb_set_suspend(struct fb_info *info, int state);
-extern int fb_get_color_depth(struct fb_info *info);
-extern int fb_get_options(char *name, char **option);
-
-extern struct fb_info *registered_fb[FB_MAX];
-extern int num_registered_fb;
+void fb_release_resources(struct list_head *head);
+int fb_remove_resource(struct fb_pixmap *resource, struct list_head *head);
+int fb_add_resource(struct fb_pixmap *resource, struct list_head *head);
+struct fb_pixmap* fb_find_resource(const char *name, struct list_head *head);
+int fb_init_resources(struct fb_info *info);
 
 /* drivers/video/fbsysfs.c */
 extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2005-02-28 20:01 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-21 19:11 Resource management James Simmons
2005-02-21 22:53 ` Antonino A. Daplas
2005-02-21 23:25   ` James Simmons
2005-02-22  1:01     ` Jon Smirl
2005-02-22  3:53       ` James Simmons
2005-02-22  4:46         ` [Linux-fbdev-devel] " Dave Airlie
2005-02-22  5:13           ` James Simmons
2005-02-22  5:59             ` [Linux-fbdev-devel] " Jon Smirl
2005-02-22  5:23           ` Jon Smirl
2005-02-22 17:23             ` James Simmons
2005-02-22 18:59               ` [Linux-fbdev-devel] " Alex Deucher
2005-02-22 13:25     ` Antonino A. Daplas
2005-02-22 14:06     ` Antonino A. Daplas
2005-02-24 19:57       ` James Simmons
2005-02-24 23:05         ` Antonino A. Daplas
2005-02-28 20:01           ` Resource management II James Simmons

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).