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"
11 #include "sys/types.h"
14 #include <sys/ioctl.h>
17 /*****************************************************************************/
19 * Initialization code shared between primary and cloned accelerants.
21 static status_t
initCommon(int the_fd
) {
23 ET6000GetPrivateData gpd
;
25 /* memorize the file descriptor */
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
;
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
);
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
) {
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
;
111 /* free up the benaphore */
112 DELETE_BEN(si
->engine
.lock
);
116 * Clean up any resources allocated in your device
117 * specific initialization code.
122 * Initialization failed after initCommon() succeeded, so we need to
123 * clean up before quiting.
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
) {
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
) {
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
);
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
;
195 /* free up the areas we cloned */
198 /* close the device we opened */
203 /*****************************************************************************/
204 void UNINIT_ACCELERANT(void) {
205 /* free our mode list area */
206 delete_area(et6000ModesListArea
);
209 /* release our cloned data */
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
;
227 /*****************************************************************************/