BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / accelerants / et6x00 / InitAccelerant.c
blob03bd387adffed64560c93cb34a18be4a9687903e
1 /*****************************************************************************\
2 * Tseng Labs ET6000, ET6100 and ET6300 graphics driver for BeOS 5.
3 * Copyright (c) 2003-2004, Evgeniy Vladimirovich Bobkov.
4 \*****************************************************************************/
6 #include "GlobalData.h"
7 #include "generic.h"
9 #include "string.h"
10 #include "unistd.h"
11 #include "sys/types.h"
12 #include "sys/stat.h"
13 #include "fcntl.h"
14 #include <sys/ioctl.h>
17 /*****************************************************************************/
19 * Initialization code shared between primary and cloned accelerants.
21 static status_t initCommon(int the_fd) {
22 status_t result;
23 ET6000GetPrivateData gpd;
25 /* memorize the file descriptor */
26 fd = the_fd;
27 /* set the magic number so the driver knows we're for real */
28 gpd.magic = ET6000_PRIVATE_DATA_MAGIC;
29 /* contact driver and get a pointer to the registers and shared data */
30 result = ioctl(fd, ET6000_GET_PRIVATE_DATA, &gpd, sizeof(gpd));
31 if (result != B_OK) goto error0;
33 /* clone the shared area for our use */
34 sharedInfoArea = clone_area("ET6000 shared info", (void **)&si,
35 B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gpd.sharedInfoArea);
36 if (sharedInfoArea < 0) {
37 result = sharedInfoArea;
38 goto error0;
41 mmRegs = si->mmRegs;
43 error0:
44 return result;
46 /*****************************************************************************/
48 * Clean up code shared between primary and cloned accelrants.
50 static void uninitCommon(void) {
51 /* release our copy of the shared info from the kernel driver */
52 delete_area(sharedInfoArea);
53 si = 0;
55 /*****************************************************************************/
57 * Initialize the accelerant. the_fd is the file handle of the device
58 * (in /dev/graphics) that has been opened by the app_server (or some test
59 * harness). We need to determine if the kernel driver and the accelerant
60 * are compatible. If they are, get the accelerant ready to handle other
61 * hook functions and report success or failure.
63 status_t INIT_ACCELERANT(int the_fd) {
64 status_t result;
66 /* note that we're the primary accelerant (accelerantIsClone is global) */
67 accelerantIsClone = 0;
69 /* do the initialization common to both the primary and the clones */
70 result = initCommon(the_fd);
72 /* bail out if the common initialization failed */
73 if (result != B_OK) goto error0;
75 /* Call the device specific initialization code here, bail out if it failed */
76 if (result != B_OK) goto error1;
79 * Now is a good time to figure out what video modes the card supports.
80 * We'll place the list of modes in another shared area so all
81 * of the copies of the driver can see them. The primary copy of the
82 * accelerant (ie the one initialized with this routine) will own the
83 * "one true copy" of the list. Everybody else get's a read-only clone.
85 result = createModesList();
86 if (result != B_OK) goto error2;
89 * We store this info in a frame_buffer_config structure to
90 * make it convienient to return to the app_server later.
92 si->fbc.frame_buffer = si->framebuffer;
93 si->fbc.frame_buffer_dma = si->physFramebuffer;
95 /* init the shared semaphore */
96 INIT_BEN(si->engine.lock);
98 /* initialize the engine synchronization variables */
100 /* count of issued parameters or commands */
101 si->engine.lastIdle = si->engine.count = 0;
103 /* bail out if something failed */
104 if (result != B_OK) goto error3;
106 /* a winner! */
107 result = B_OK;
108 goto error0;
110 error3:
111 /* free up the benaphore */
112 DELETE_BEN(si->engine.lock);
114 error2:
116 * Clean up any resources allocated in your device
117 * specific initialization code.
120 error1:
122 * Initialization failed after initCommon() succeeded, so we need to
123 * clean up before quiting.
125 uninitCommon();
127 error0:
128 return result;
130 /*****************************************************************************/
132 * Return the number of bytes required to hold the information required
133 * to clone the device.
135 ssize_t ACCELERANT_CLONE_INFO_SIZE(void) {
137 * Since we're passing the name of the device as the only required
138 * info, return the size of the name buffer
140 return B_OS_NAME_LENGTH;
142 /*****************************************************************************/
144 * Return the info required to clone the device. void *data points to
145 * a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length.
147 void GET_ACCELERANT_CLONE_INFO(void *data) {
148 ET6000DeviceName dn;
149 status_t result;
151 /* call the kernel driver to get the device name */
152 dn.magic = ET6000_PRIVATE_DATA_MAGIC;
153 /* store the returned info directly into the passed buffer */
154 dn.name = (char *)data;
155 result = ioctl(fd, ET6000_DEVICE_NAME, &dn, sizeof(dn));
157 /*****************************************************************************/
159 * Initialize a copy of the accelerant as a clone. void *data points
160 * to a copy of the data returned by GET_ACCELERANT_CLONE_INFO().
162 status_t CLONE_ACCELERANT(void *data) {
163 status_t result;
164 char path[MAXPATHLEN];
166 /* the data is the device name */
167 strcpy(path, "/dev/");
168 strcat(path, (const char *)data);
169 /* open the device, the permissions aren't important */
170 fd = open(path, B_READ_WRITE);
171 if (fd < 0) {
172 result = fd;
173 goto error0;
176 /* note that we're a clone accelerant */
177 accelerantIsClone = 1;
179 /* call the shared initialization code */
180 result = initCommon(fd);
182 /* bail out if the common initialization failed */
183 if (result != B_OK) goto error1;
185 /* get shared area for display modes */
186 result = et6000ModesListArea = clone_area("ET6000 cloned display_modes",
187 (void **)&et6000ModesList, B_ANY_ADDRESS, B_READ_AREA, si->modesArea);
188 if (result < B_OK) goto error2;
190 /* all done */
191 result = B_OK;
192 goto error0;
194 error2:
195 /* free up the areas we cloned */
196 uninitCommon();
197 error1:
198 /* close the device we opened */
199 close(fd);
200 error0:
201 return result;
203 /*****************************************************************************/
204 void UNINIT_ACCELERANT(void) {
205 /* free our mode list area */
206 delete_area(et6000ModesListArea);
207 et6000ModesList = 0;
209 /* release our cloned data */
210 uninitCommon();
212 /* close the file handle ONLY if we're the clone */
213 if (accelerantIsClone) close(fd);
215 /*****************************************************************************/
216 status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
218 adi->version = B_ACCELERANT_VERSION;
219 strcpy(adi->name, "Tseng Labs ET6x00");
220 strcpy(adi->chipset, "Tseng Labs ET6x00");
221 strcpy(adi->serial_no, "");
222 adi->memory = si->memSize;
223 adi->dac_speed = si->pixelClockMax16;
225 return B_OK;
227 /*****************************************************************************/