xref: /kvmtool/framebuffer.c (revision ba46fe53c6deed93c55409c02c9f9a2dee61848e)
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>
748d9e01aSSasha 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)
2248d9e01aSSasha 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 
47*ba46fe53SSasha Levin int fb__init(struct kvm *kvm)
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 
62*ba46fe53SSasha Levin int fb__exit(struct kvm *kvm)
6308e89f1eSPekka Enberg {
6408e89f1eSPekka Enberg 	struct framebuffer *fb;
6508e89f1eSPekka Enberg 
6608e89f1eSPekka Enberg 	list_for_each_entry(fb, &framebuffers, node) {
6748d9e01aSSasha Levin 		u32 i;
6848d9e01aSSasha Levin 
6948d9e01aSSasha Levin 		for (i = 0; i < fb->nr_targets; i++)
7048d9e01aSSasha Levin 			if (fb->targets[i]->stop)
7148d9e01aSSasha Levin 				fb->targets[i]->stop(fb);
7248d9e01aSSasha Levin 
737fca1897SSasha Levin 		munmap(fb->mem, fb->mem_size);
7408e89f1eSPekka Enberg 	}
75*ba46fe53SSasha Levin 
76*ba46fe53SSasha Levin 	return 0;
7708e89f1eSPekka Enberg }
78