BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / graphics / radeon_hd / device.cpp
bloba5aba50552180b0c19120f48fc44b1c550727a53
1 /*
2 * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
10 #include "driver.h"
11 #include "device.h"
12 #include "radeon_hd.h"
13 #include "utility.h"
15 #include <OS.h>
16 #include <KernelExport.h>
17 #include <Drivers.h>
18 #include <PCI.h>
19 #include <SupportDefs.h>
20 #include <graphic_driver.h>
21 #include <image.h>
23 #include <stdlib.h>
24 #include <string.h>
27 //#define DEBUG_COMMANDS
29 #define TRACE_DEVICE
30 #ifdef TRACE_DEVICE
31 # define TRACE(x...) dprintf("radeon_hd: " x)
32 #else
33 # define TRACE(x...) ;
34 #endif
36 #define ERROR(x...) dprintf("radeon_hd: " x)
39 /* device hooks prototypes */
41 static status_t device_open(const char* name, uint32 flags, void** _cookie);
42 static status_t device_close(void* data);
43 static status_t device_free(void* data);
44 static status_t device_ioctl(void* data, uint32 opcode,
45 void* buffer, size_t length);
46 static status_t device_read(void* data, off_t offset,
47 void* buffer, size_t* length);
48 static status_t device_write(void* data, off_t offset,
49 const void* buffer, size_t* length);
52 device_hooks gDeviceHooks = {
53 device_open,
54 device_close,
55 device_free,
56 device_ioctl,
57 device_read,
58 device_write,
59 NULL,
60 NULL,
61 NULL,
62 NULL
66 #ifdef DEBUG_COMMANDS
67 static int
68 getset_register(int argc, char** argv)
70 if (argc < 2 || argc > 3) {
71 kprintf("usage: %s <register> [set-to-value]\n", argv[0]);
72 return 0;
75 uint32 reg = parse_expression(argv[1]);
76 uint32 value = 0;
77 bool set = argc == 3;
78 if (set)
79 value = parse_expression(argv[2]);
81 kprintf("radeon_hd register %#lx\n", reg);
83 radeon_info &info = *gDeviceInfo[0];
84 uint32 oldValue = read32(info.registers + reg);
86 kprintf(" %svalue: %#lx (%lu)\n", set ? "old " : "", oldValue, oldValue);
88 if (set) {
89 write32(info.registers + reg, value);
91 value = read32(info.registers + reg);
92 kprintf(" new value: %#lx (%lu)\n", value, value);
95 return 0;
97 #endif // DEBUG_COMMANDS
100 // #pragma mark - Device Hooks
103 static status_t
104 device_open(const char* name, uint32 /*flags*/, void** _cookie)
106 TRACE("%s: open(name = %s)\n", __func__, name);
107 int32 id;
109 // find accessed device
111 char* thisName;
113 // search for device name
114 for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) {
115 if (!strcmp(name, thisName))
116 break;
118 if (!thisName)
119 return B_BAD_VALUE;
122 radeon_info* info = gDeviceInfo[id];
124 mutex_lock(&gLock);
126 if (info->open_count == 0) {
127 // This device hasn't been initialized yet, so we
128 // allocate needed resources and initialize the structure
129 info->init_status = radeon_hd_init(*info);
130 if (info->init_status == B_OK) {
131 #ifdef DEBUG_COMMANDS
132 add_debugger_command("radeonhd_reg", getset_register,
133 "dumps or sets the specified radeon_hd register");
134 #endif
138 if (info->init_status == B_OK) {
139 info->open_count++;
140 *_cookie = info;
141 } else
142 ERROR("%s: initialization failed!\n", __func__);
144 mutex_unlock(&gLock);
146 return info->init_status;
150 static status_t
151 device_close(void* /*data*/)
153 TRACE("%s: close\n", __func__);
154 return B_OK;
158 static status_t
159 device_free(void* data)
161 struct radeon_info* info = (radeon_info*)data;
163 mutex_lock(&gLock);
165 if (info->open_count-- == 1) {
166 // release info structure
167 info->init_status = B_NO_INIT;
168 radeon_hd_uninit(*info);
170 #ifdef DEBUG_COMMANDS
171 remove_debugger_command("radeonhd_reg", getset_register);
172 #endif
175 mutex_unlock(&gLock);
176 return B_OK;
180 static status_t
181 device_ioctl(void* data, uint32 op, void* buffer, size_t bufferLength)
183 struct radeon_info* info = (radeon_info*)data;
185 switch (op) {
186 case B_GET_ACCELERANT_SIGNATURE:
187 strcpy((char*)buffer, RADEON_ACCELERANT_NAME);
188 TRACE("%s: accelerant: %s\n", __func__, RADEON_ACCELERANT_NAME);
189 return B_OK;
191 // needed to share data between kernel and accelerant
192 case RADEON_GET_PRIVATE_DATA:
194 radeon_get_private_data* data = (radeon_get_private_data*)buffer;
196 if (data->magic == RADEON_PRIVATE_DATA_MAGIC) {
197 data->shared_info_area = info->shared_area;
198 return B_OK;
200 break;
203 // needed for cloning
204 case RADEON_GET_DEVICE_NAME:
205 #ifdef __HAIKU__
206 if (user_strlcpy((char*)buffer, gDeviceNames[info->id],
207 B_PATH_NAME_LENGTH) < B_OK)
208 return B_BAD_ADDRESS;
209 #else
210 strncpy((char*)buffer, gDeviceNames[info->id], B_PATH_NAME_LENGTH);
211 ((char*)buffer)[B_PATH_NAME_LENGTH - 1] = '\0';
212 #endif
213 return B_OK;
215 default:
216 TRACE("%s: ioctl() unknown message %ld (length = %ld)\n",
217 __func__, op, bufferLength);
218 break;
221 return B_DEV_INVALID_IOCTL;
225 static status_t
226 device_read(void* /*data*/, off_t /*pos*/,
227 void* /*buffer*/, size_t *_length)
229 *_length = 0;
230 return B_NOT_ALLOWED;
234 static status_t
235 device_write(void* /*data*/, off_t /*pos*/,
236 const void* /*buffer*/, size_t* _length)
238 *_length = 0;
239 return B_NOT_ALLOWED;