All of lore.kernel.org
 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; 22+ 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] 22+ messages in thread

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

Thread overview: 22+ 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  3:53         ` [Linux-fbdev-devel] " James Simmons
2005-02-22  4:46         ` Dave Airlie
2005-02-22  5:13           ` James Simmons
2005-02-22  5:13             ` [Linux-fbdev-devel] " James Simmons
2005-02-22  5:59             ` Jon Smirl
2005-02-22  5:59               ` Jon Smirl
2005-02-22  5:23           ` Jon Smirl
2005-02-22  5:23             ` Jon Smirl
2005-02-22 17:23             ` James Simmons
2005-02-22 17:23               ` [Linux-fbdev-devel] " James Simmons
2005-02-22 18:59               ` Alex Deucher
2005-02-22 18:59                 ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.