* Tseng Labs ET6000, ET6100 and ET6300 graphics driver for BeOS 5.
* Copyright (c) 2003-2004, Evgeniy Vladimirovich Bobkov.
\*****************************************************************************/
#include "GlobalData.h"
#include "generic.h"
#include "string.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include <sys/ioctl.h>
* Initialization code shared between primary and cloned accelerants.
*/
static status_t initCommon(int the_fd) {
status_t result;
ET6000GetPrivateData gpd;
fd = the_fd;
gpd.magic = ET6000_PRIVATE_DATA_MAGIC;
result = ioctl(fd, ET6000_GET_PRIVATE_DATA, &gpd, sizeof(gpd));
if (result != B_OK) goto error0;
sharedInfoArea = clone_area("ET6000 shared info", (void **)&si,
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gpd.sharedInfoArea);
if (sharedInfoArea < 0) {
result = sharedInfoArea;
goto error0;
}
mmRegs = si->mmRegs;
error0:
return result;
}
* Clean up code shared between primary and cloned accelrants.
*/
static void uninitCommon(void) {
delete_area(sharedInfoArea);
si = 0;
}
* Initialize the accelerant. the_fd is the file handle of the device
* (in /dev/graphics) that has been opened by the app_server (or some test
* harness). We need to determine if the kernel driver and the accelerant
* are compatible. If they are, get the accelerant ready to handle other
* hook functions and report success or failure.
*/
status_t INIT_ACCELERANT(int the_fd) {
status_t result;
accelerantIsClone = 0;
result = initCommon(the_fd);
if (result != B_OK) goto error0;
if (result != B_OK) goto error1;
* Now is a good time to figure out what video modes the card supports.
* We'll place the list of modes in another shared area so all
* of the copies of the driver can see them. The primary copy of the
* accelerant (ie the one initialized with this routine) will own the
* "one true copy" of the list. Everybody else get's a read-only clone.
*/
result = createModesList();
if (result != B_OK) goto error2;
* We store this info in a frame_buffer_config structure to
* make it convienient to return to the app_server later.
*/
si->fbc.frame_buffer = si->framebuffer;
si->fbc.frame_buffer_dma = si->physFramebuffer;
INIT_BEN(si->engine.lock);
si->engine.lastIdle = si->engine.count = 0;
if (result != B_OK) goto error3;
result = B_OK;
goto error0;
error3:
DELETE_BEN(si->engine.lock);
error2:
* Clean up any resources allocated in your device
* specific initialization code.
*/
error1:
* Initialization failed after initCommon() succeeded, so we need to
* clean up before quiting.
*/
uninitCommon();
error0:
return result;
}
* Return the number of bytes required to hold the information required
* to clone the device.
*/
ssize_t ACCELERANT_CLONE_INFO_SIZE(void) {
* Since we're passing the name of the device as the only required
* info, return the size of the name buffer
*/
return B_OS_NAME_LENGTH;
}
* Return the info required to clone the device. void *data points to
* a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length.
*/
void GET_ACCELERANT_CLONE_INFO(void *data) {
ET6000DeviceName dn;
status_t result;
dn.magic = ET6000_PRIVATE_DATA_MAGIC;
dn.name = (char *)data;
result = ioctl(fd, ET6000_DEVICE_NAME, &dn, sizeof(dn));
}
* Initialize a copy of the accelerant as a clone. void *data points
* to a copy of the data returned by GET_ACCELERANT_CLONE_INFO().
*/
status_t CLONE_ACCELERANT(void *data) {
status_t result;
char path[MAXPATHLEN];
strcpy(path, "/dev/");
strcat(path, (const char *)data);
fd = open(path, B_READ_WRITE);
if (fd < 0) {
result = fd;
goto error0;
}
accelerantIsClone = 1;
result = initCommon(fd);
if (result != B_OK) goto error1;
result = et6000ModesListArea = clone_area("ET6000 cloned display_modes",
(void **)&et6000ModesList, B_ANY_ADDRESS, B_READ_AREA, si->modesArea);
if (result < B_OK) goto error2;
result = B_OK;
goto error0;
error2:
uninitCommon();
error1:
close(fd);
error0:
return result;
}
void UNINIT_ACCELERANT(void) {
delete_area(et6000ModesListArea);
et6000ModesList = 0;
uninitCommon();
if (accelerantIsClone) close(fd);
}
status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
{
adi->version = B_ACCELERANT_VERSION;
strcpy(adi->name, "Tseng Labs ET6x00");
strcpy(adi->chipset, "Tseng Labs ET6x00");
strcpy(adi->serial_no, "");
adi->memory = si->memSize;
adi->dac_speed = si->pixelClockMax16;
return B_OK;
}