1/* 2 * Copyright 1999, Be Incorporated. 3 * Copyright 2007, Haiku. 4 * Distributed under the terms of the MIT License. 5 * 6 * Authors: 7 * Be Incorporated 8 * Eric Petit <eric.petit@lapsus.org> 9 */ 10 11#include "string.h" 12#include "unistd.h" 13#include "sys/types.h" 14#include "sys/stat.h" 15#include "fcntl.h" 16#include <sys/ioctl.h> 17#include <SupportDefs.h> 18 19#include "GlobalData.h" 20 21 22/* Initialization code shared between primary and cloned accelerants */ 23static 24status_t InitCommon(int fd) 25{ 26 status_t ret; 27 28 /* Memorize the file descriptor */ 29 gFd = fd; 30 31 /* Contact driver and get a pointer to the registers and shared data */ 32 if ((ret = ioctl(gFd, VMWARE_GET_PRIVATE_DATA, &gSharedArea, 33 sizeof(area_id))) != B_OK) { 34 TRACE("VMWARE_GET_PRIVATE_DATA failed (%"B_PRIx32"\n", ret); 35 return ret; 36 } 37 38 /* Clone the shared area for our use */ 39 if ((gSharedArea = clone_area("VMware shared", (void **)&gSi, 40 B_ANY_ADDRESS, B_READ_AREA|B_WRITE_AREA, gSharedArea)) < 0) { 41 TRACE("could not clone shared area (%"B_PRId32")\n", gSharedArea); 42 return gSharedArea; 43 } 44 45 return B_OK; 46} 47 48 49static void 50UninitCommon() 51{ 52 delete_area(gSharedArea); 53} 54 55 56status_t 57INIT_ACCELERANT(int fd) 58{ 59 status_t ret; 60 61 TRACE("INIT_ACCELERANT (%d)\n", fd); 62 63 gAccelerantIsClone = 0; 64 65 /* Common initialization for the primary accelerant and clones */ 66 if ((ret = InitCommon(fd)) == B_OK) { 67 /* Init semaphores */ 68 INIT_BEN(gSi->engineLock); 69 INIT_BEN(gSi->fifoLock); 70 } 71 72 TRACE("INIT_ACCELERANT: %"B_PRIx32"\n", ret); 73 return ret; 74} 75 76 77ssize_t 78ACCELERANT_CLONE_INFO_SIZE() 79{ 80 return B_PATH_NAME_LENGTH; 81} 82 83 84void 85GET_ACCELERANT_CLONE_INFO(void *data) 86{ 87 TRACE("GET_ACCELERANT_CLONE_INFO (%d)\n", gFd); 88 89 // TODO: I have no idea why this doesn't work: gFd is 0 here !?!? 90 //ioctl(gFd, VMWARE_GET_DEVICE_NAME, data, B_PATH_NAME_LENGTH); 91 strlcpy(data, "graphics/vmware", B_PATH_NAME_LENGTH); 92 93} 94 95 96status_t 97CLONE_ACCELERANT(void *data) 98{ 99 int fd; 100 char path[B_PATH_NAME_LENGTH]; 101 status_t ret; 102 103 // create full device name 104 strcpy(path, "/dev/"); 105 strlcat(path, (const char *)data, sizeof(path)); 106 107 TRACE("CLONE_ACCELERANT: %s\n", (const char *)path); 108 109 fd = open(path, B_READ_WRITE); 110 if (fd < 0) 111 return fd; 112 113 gAccelerantIsClone = 1; 114 115 /* Common initialization for the primary accelerant and clones */ 116 if ((ret = InitCommon(fd)) == B_OK) { 117 /* Init semaphores */ 118 INIT_BEN(gSi->engineLock); 119 INIT_BEN(gSi->fifoLock); 120 } 121 122 TRACE("CLONE_ACCELERANT: %"B_PRIx32"\n", ret); 123 return ret; 124} 125 126 127void 128UNINIT_ACCELERANT() 129{ 130 UninitCommon(); 131 if (gAccelerantIsClone) 132 close(gFd); 133 else if (gUpdateThread > B_OK) { 134 status_t exitValue; 135 gUpdateThreadDie = 1; 136 wait_for_thread(gUpdateThread, &exitValue); 137 } 138 ioctl(gFd, VMWARE_FIFO_STOP, NULL, 0); 139} 140 141