xref: /haiku/src/add-ons/kernel/drivers/graphics/vesa/device.cpp (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
1 /*
2  * Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "device.h"
8 #include "driver.h"
9 #include "utility.h"
10 #include "vesa_info.h"
11 #include "vga.h"
12 
13 #include <OS.h>
14 #include <KernelExport.h>
15 #include <Drivers.h>
16 #include <PCI.h>
17 #include <SupportDefs.h>
18 #include <graphic_driver.h>
19 #include <image.h>
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 
25 //#define TRACE_DEVICE
26 #ifdef TRACE_DEVICE
27 #	define TRACE(x) dprintf x
28 #else
29 #	define TRACE(x) ;
30 #endif
31 
32 
33 /* device hooks prototypes */
34 
35 static status_t device_open(const char *, uint32, void **);
36 static status_t device_close(void *);
37 static status_t device_free(void *);
38 static status_t device_ioctl(void *, uint32, void *, size_t);
39 static status_t device_read(void *, off_t, void *, size_t *);
40 static status_t device_write(void *, off_t, const void *, size_t *);
41 
42 
43 device_hooks gDeviceHooks = {
44 	device_open,
45 	device_close,
46 	device_free,
47 	device_ioctl,
48 	device_read,
49 	device_write,
50 	NULL,
51 	NULL,
52 	NULL,
53 	NULL
54 };
55 
56 
57 //	#pragma mark -
58 //	the device will be accessed through the following functions (a.k.a. device hooks)
59 
60 
61 static status_t
62 device_open(const char *name, uint32 flags, void **_cookie)
63 {
64 	int id;
65 
66 	// find accessed device
67 	{
68 		char *thisName;
69 
70 		// search for device name
71 		for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) {
72 			if (!strcmp(name, thisName))
73 				break;
74 		}
75 		if (!thisName)
76 			return EINVAL;
77 	}
78 
79 	vesa_info *info = gDeviceInfo[id];
80 	*_cookie = info;
81 
82 	acquire_lock(&gLock);
83 
84 	status_t status = B_OK;
85 
86 	if (info->open_count++ == 0) {
87 		// this device has been opened for the first time, so
88 		// we allocate needed resources and initialize the structure
89 		if (status == B_OK)
90 			status = vesa_init(*info);
91 		if (status == B_OK)
92 			info->id = id;
93 	}
94 
95 	release_lock(&gLock);
96 	return status;
97 }
98 
99 
100 static status_t
101 device_close(void *cookie)
102 {
103 	return B_OK;
104 }
105 
106 
107 static status_t
108 device_free(void *cookie)
109 {
110 	struct vesa_info *info = (vesa_info *)cookie;
111 
112 	acquire_lock(&gLock);
113 
114 	if (info->open_count-- == 1) {
115 		// release info structure
116 		vesa_uninit(*info);
117 	}
118 
119 	release_lock(&gLock);
120 	return B_OK;
121 }
122 
123 
124 static status_t
125 device_ioctl(void *cookie, uint32 msg, void *buffer, size_t bufferLength)
126 {
127 	struct vesa_info *info = (vesa_info *)cookie;
128 
129 	switch (msg) {
130 		case B_GET_ACCELERANT_SIGNATURE:
131 			user_strlcpy((char *)buffer, VESA_ACCELERANT_NAME, B_FILE_NAME_LENGTH);
132 			dprintf(DEVICE_NAME ": acc: %s\n", VESA_ACCELERANT_NAME);
133 			return B_OK;
134 
135 		// needed to share data between kernel and accelerant
136 		case VESA_GET_PRIVATE_DATA:
137 			return user_memcpy(buffer, &info->shared_area, sizeof(area_id));
138 
139 		// needed for cloning
140 		case VESA_GET_DEVICE_NAME:
141 			if (user_strlcpy((char *)buffer, gDeviceNames[info->id], B_PATH_NAME_LENGTH) < B_OK)
142 				return B_BAD_ADDRESS;
143 			return B_OK;
144 
145 		case VGA_SET_INDEXED_COLORS:
146 		{
147 			vga_set_indexed_colors_args args;
148 			if (user_memcpy(&args, buffer, sizeof(args)) < B_OK)
149 				return B_BAD_ADDRESS;
150 
151 			return vga_set_indexed_colors(args.first, args.colors, args.count);
152 		}
153 
154 		case VGA_PLANAR_BLIT:
155 		{
156 			vga_planar_blit_args args;
157 			if (user_memcpy(&args, buffer, sizeof(args)) < B_OK)
158 				return B_BAD_ADDRESS;
159 
160 			return vga_planar_blit(info->shared_info, args.source,
161 				args.source_bytes_per_row, args.left, args.top,
162 				args.right, args.bottom);
163 		}
164 
165 		default:
166 			TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %lu)\n", msg, bufferLength));
167 	}
168 
169 	return B_DEV_INVALID_IOCTL;
170 }
171 
172 
173 static status_t
174 device_read(void */*cookie*/, off_t /*pos*/, void */*buffer*/, size_t *_length)
175 {
176 	*_length = 0;
177 	return B_NOT_ALLOWED;
178 }
179 
180 
181 static status_t
182 device_write(void */*cookie*/, off_t /*pos*/, const void */*buffer*/, size_t *_length)
183 {
184 	*_length = 0;
185 	return B_NOT_ALLOWED;
186 }
187 
188