xref: /kvmtool/framebuffer.c (revision 48d9e01a8cfb8541c32c1dd46fa9d34fc687b031)
108e89f1eSPekka Enberg #include "kvm/framebuffer.h"
208e89f1eSPekka Enberg 
308e89f1eSPekka Enberg #include <linux/kernel.h>
408e89f1eSPekka Enberg #include <linux/list.h>
508e89f1eSPekka Enberg #include <stdlib.h>
67fca1897SSasha Levin #include <sys/mman.h>
7*48d9e01aSSasha Levin #include <errno.h>
808e89f1eSPekka Enberg 
908e89f1eSPekka Enberg static LIST_HEAD(framebuffers);
1008e89f1eSPekka Enberg 
1108e89f1eSPekka Enberg struct framebuffer *fb__register(struct framebuffer *fb)
1208e89f1eSPekka Enberg {
1308e89f1eSPekka Enberg 	INIT_LIST_HEAD(&fb->node);
1408e89f1eSPekka Enberg 	list_add(&fb->node, &framebuffers);
1508e89f1eSPekka Enberg 
1608e89f1eSPekka Enberg 	return fb;
1708e89f1eSPekka Enberg }
1808e89f1eSPekka Enberg 
1908e89f1eSPekka Enberg int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops)
2008e89f1eSPekka Enberg {
2108e89f1eSPekka Enberg 	if (fb->nr_targets >= FB_MAX_TARGETS)
22*48d9e01aSSasha Levin 		return -ENOSPC;
2308e89f1eSPekka Enberg 
2408e89f1eSPekka Enberg 	fb->targets[fb->nr_targets++] = ops;
2508e89f1eSPekka Enberg 
2608e89f1eSPekka Enberg 	return 0;
2708e89f1eSPekka Enberg }
2808e89f1eSPekka Enberg 
2908e89f1eSPekka Enberg static int start_targets(struct framebuffer *fb)
3008e89f1eSPekka Enberg {
3108e89f1eSPekka Enberg 	unsigned long i;
3208e89f1eSPekka Enberg 
3308e89f1eSPekka Enberg 	for (i = 0; i < fb->nr_targets; i++) {
3408e89f1eSPekka Enberg 		struct fb_target_operations *ops = fb->targets[i];
3508e89f1eSPekka Enberg 		int err = 0;
3608e89f1eSPekka Enberg 
3708e89f1eSPekka Enberg 		if (ops->start)
3808e89f1eSPekka Enberg 			err = ops->start(fb);
3908e89f1eSPekka Enberg 
4008e89f1eSPekka Enberg 		if (err)
4108e89f1eSPekka Enberg 			return err;
4208e89f1eSPekka Enberg 	}
4308e89f1eSPekka Enberg 
4408e89f1eSPekka Enberg 	return 0;
4508e89f1eSPekka Enberg }
4608e89f1eSPekka Enberg 
4708e89f1eSPekka Enberg int fb__start(void)
4808e89f1eSPekka Enberg {
4908e89f1eSPekka Enberg 	struct framebuffer *fb;
5008e89f1eSPekka Enberg 
5108e89f1eSPekka Enberg 	list_for_each_entry(fb, &framebuffers, node) {
5208e89f1eSPekka Enberg 		int err;
5308e89f1eSPekka Enberg 
5408e89f1eSPekka Enberg 		err = start_targets(fb);
5508e89f1eSPekka Enberg 		if (err)
5608e89f1eSPekka Enberg 			return err;
5708e89f1eSPekka Enberg 	}
5808e89f1eSPekka Enberg 
5908e89f1eSPekka Enberg 	return 0;
6008e89f1eSPekka Enberg }
6108e89f1eSPekka Enberg 
6208e89f1eSPekka Enberg void fb__stop(void)
6308e89f1eSPekka Enberg {
6408e89f1eSPekka Enberg 	struct framebuffer *fb;
6508e89f1eSPekka Enberg 
6608e89f1eSPekka Enberg 	list_for_each_entry(fb, &framebuffers, node) {
67*48d9e01aSSasha Levin 		u32 i;
68*48d9e01aSSasha Levin 
69*48d9e01aSSasha Levin 		for (i = 0; i < fb->nr_targets; i++)
70*48d9e01aSSasha Levin 			if (fb->targets[i]->stop)
71*48d9e01aSSasha Levin 				fb->targets[i]->stop(fb);
72*48d9e01aSSasha Levin 
737fca1897SSasha Levin 		munmap(fb->mem, fb->mem_size);
7408e89f1eSPekka Enberg 	}
7508e89f1eSPekka Enberg }
76