示例#1
0
static status_t
InitCommon(int fileDesc)
{
	// Initialization function used by primary and cloned accelerants.

	gInfo.deviceFileDesc = fileDesc;

	// Get area ID of shared data from driver.

	area_id sharedArea;
	status_t result = ioctl(gInfo.deviceFileDesc, TDFX_GET_SHARED_DATA,
		&sharedArea, sizeof(sharedArea));
	if (result != B_OK)
		return result;

	gInfo.sharedInfoArea = clone_area("3DFX shared info", 
		(void**)&(gInfo.sharedInfo), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA,
		 sharedArea);
	if (gInfo.sharedInfoArea < 0)
		return gInfo.sharedInfoArea;	// sharedInfoArea has error code

	gInfo.regsArea = clone_area("3DFX regs area", (void**)&(gInfo.regs),
		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gInfo.sharedInfo->regsArea);
	if (gInfo.regsArea < 0) {
		delete_area(gInfo.sharedInfoArea);
		return gInfo.regsArea;		// regsArea has error code
	}

	return B_OK;
}
示例#2
0
/* Initialization code shared between primary and cloned accelerants */
static status_t init_common(int the_fd)
{
	status_t result;
	gx00_get_private_data gpd;
	
	// LOG not available from here to next LOG: NULL si

	/* memorize the file descriptor */
	fd = the_fd;
	/* set the magic number so the driver knows we're for real */
	gpd.magic = GX00_PRIVATE_DATA_MAGIC;
	/* contact driver and get a pointer to the registers and shared data */
	result = ioctl(fd, GX00_GET_PRIVATE_DATA, &gpd, sizeof(gpd));
	if (result != B_OK) goto error0;

	/* clone the shared area for our use */
	shared_info_area = clone_area(DRIVER_PREFIX " shared", (void **)&si, B_ANY_ADDRESS,
		B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area);
	if (shared_info_area < 0) {
			result = shared_info_area;
			goto error0;
	}
	// LOG is now available, si !NULL
	LOG(4,("init_common: logmask 0x%08x, memory %dMB, hardcursor %d, usebios %d, greensync %d\n",
		si->settings.logmask, si->settings.memory, si->settings.hardcursor, si->settings.usebios, si->settings.greensync));

 	/*Check for R4.5.0 and if it is running, use work around*/
 	{
 		if (si->use_clone_bugfix)
 		{
 			/*check for R4.5.0 bug and attempt to work around*/
 			LOG(2,("InitACC: Found R4.5.0 bug - attempting to work around\n"));
 			regs = si->clone_bugfix_regs;
 		}
 		else
 		{
			/* clone the memory mapped registers for our use  - does not work on <4.5.2 (but is better this way)*/
			regs_area = clone_area(DRIVER_PREFIX " regs", (void **)&regs, B_ANY_ADDRESS,
				B_READ_AREA | B_WRITE_AREA, si->regs_area);
			if (regs_area < 0) {
				result = regs_area;
				goto error1;
			}
 		}
 	}

	/*FIXME - print dma addresses*/
	//LOG(4,("DMA_virtual:%x\tDMA_physical:%x\tDMA_area:%x\n",si->dma_buffer,si->dma_buffer_pci,si->dma_buffer_area));

	/* all done */
	goto error0;

error1:
	delete_area(shared_info_area);
error0:
	return result;
}
示例#3
0
status_t
vesa_clone_accelerant(void *info)
{
	TRACE(("vesa_clone_accelerant()\n"));

	// create full device name
	char path[MAXPATHLEN];
	strcpy(path, "/dev/");
	strcat(path, (const char *)info);

	int fd = open(path, B_READ_WRITE);
	if (fd < 0)
		return errno;

	status_t status = init_common(fd, true);
	if (status != B_OK)
		goto err1;

	// get read-only clone of supported display modes
	status = gInfo->mode_list_area = clone_area(
		"vesa cloned modes", (void **)&gInfo->mode_list,
		B_ANY_ADDRESS, B_READ_AREA, gInfo->shared_info->mode_list_area);
	if (status < B_OK)
		goto err2;

	return B_OK;

err2:
	uninit_common();
err1:
	close(fd);
	return status;
}
示例#4
0
status_t
BufferManager::RegisterBuffer(team_id teamid, size_t size, int32 flags, size_t offset, area_id area,
							  media_buffer_id *bufferid)
{
	BAutolock lock(fLocker);
	TRACE("RegisterBuffer team = %ld, areaid = %ld, offset = %ld, size = %ld\n", teamid, area, offset, size);
	
	void *adr;
	area_id newarea;

	newarea = clone_area("media_server cloned buffer", &adr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
	if (newarea <= B_OK) {
		ERROR("RegisterBuffer: failed to clone buffer! error = %#lx, team = %ld, areaid = %ld, offset = %ld, size = %ld\n", newarea, teamid, area, offset, size);
		return B_ERROR;
	}

	buffer_info info;

	*bufferid	= fNextBufferId;
	info.id 	= fNextBufferId;
	info.area 	= newarea;
	info.offset = offset;
	info.size 	= size;
	info.flags	= flags;
	info.teams.Insert(teamid);
	fBufferInfoMap->Insert(fNextBufferId, info);

	TRACE("RegisterBuffer: done, bufferid = %ld\n", fNextBufferId);

	fNextBufferId += 1;
	
	return B_OK;
}
示例#5
0
area_id
AreaCloner::Clone(const char* name, void** _address, uint32 spec,
	uint32 protection, area_id sourceArea)
{
	fArea = clone_area(name, _address, spec, protection, sourceArea);
	return fArea;
}
示例#6
0
status_t
CloneAccelerant(void* data)
{
	// Initialize a copy of the accelerant as a clone.  Argument data points to
	// a copy of the data which was returned by GetAccelerantCloneInfo().

	TRACE("Enter CloneAccelerant()\n");

	char path[MAXPATHLEN] = "/dev/";
	strcat(path, (const char*)data);

	gInfo.deviceFileDesc = open(path, B_READ_WRITE);	// open the device
	if (gInfo.deviceFileDesc < 0)
		return errno;

	gInfo.bAccelerantIsClone = true;

	status_t result = InitCommon(gInfo.deviceFileDesc);
	if (result != B_OK) {
		close(gInfo.deviceFileDesc);
		return result;
	}

	result = gInfo.modeListArea = clone_area("ATI cloned display_modes",
		(void**) &gInfo.modeList, B_ANY_ADDRESS, B_READ_AREA,
		gInfo.sharedInfo->modeArea);
	if (result < 0) {
		UninitCommon();
		close(gInfo.deviceFileDesc);
		return result;
	}

	TRACE("Leave CloneAccelerant()\n");
	return B_OK;
}
示例#7
0
/* explicit */
BTimeSource::BTimeSource(media_node_id id) :
	BMediaNode("This one is never called"),
	fStarted(false),
	fArea(-1),
	fBuf(NULL),
	fSlaveNodes(NULL),
	fIsRealtime(false)
{
	CALLED();
	AddNodeKind(B_TIME_SOURCE);
	ASSERT(id > 0);
//	printf("###### explicit BTimeSource::BTimeSource() id %ld, name %s\n", id, Name());

	// This constructor is only called by the derived BPrivate::media::TimeSourceObject objects
	// We create a clone of the communication area
	char name[32];
	area_id area;
	sprintf(name, "__timesource_buf_%" B_PRId32, id);
	area = find_area(name);
	if (area <= 0) {
		ERROR("BTimeSource::BTimeSource couldn't find area, node %" B_PRId32
			"\n", id);
		return;
	}
	sprintf(name, "__cloned_timesource_buf_%" B_PRId32, id);
	fArea = clone_area(name, reinterpret_cast<void **>(const_cast<BPrivate::media::TimeSourceTransmit **>(&fBuf)), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
	if (fArea <= 0) {
		ERROR("BTimeSource::BTimeSource couldn't clone area, node %" B_PRId32
			"\n", id);
		return;
	}
}
void*
ClonedAreaMemory::Clone(area_id area, uint32 offset)
{
	fClonedArea = clone_area("server_memory", (void**)&fBase, B_ANY_ADDRESS,
		B_READ_AREA | B_WRITE_AREA, area);
	if (fBase == NULL)
		return NULL;
	fOffset = offset;
	return Address();
}
示例#9
0
static status_t 
InitCommon(int fileDesc)
{
	// Initialization function used by primary and cloned accelerants.

	gInfo.deviceFileDesc = fileDesc;

	// Get pointer to registers and shared data from driver.

	S3GetPrivateData gpd;
	gpd.magic = S3_PRIVATE_DATA_MAGIC;

	status_t result = ioctl(gInfo.deviceFileDesc, S3_GET_PRIVATE_DATA, &gpd, sizeof(gpd));
	if (result != B_OK)
		return result;

	gInfo.sharedInfoArea = clone_area("S3 shared info", (void**)&(gInfo.sharedInfo),
		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gpd.sharedInfoArea);
	if (gInfo.sharedInfoArea < 0)
		return gInfo.sharedInfoArea;	// sharedInfoArea has error code

	gInfo.regsArea = clone_area("S3 regs area", (void**)&(gInfo.regs),
		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gInfo.sharedInfo->regsArea);
	if (gInfo.regsArea < 0) {
		delete_area(gInfo.sharedInfoArea);
		return gInfo.regsArea;		// regsArea has error code
	}

	// Set pointers to various device specific functions.

	if (S3_SAVAGE_FAMILY(gInfo.sharedInfo->chipType))
		Savage_SetFunctionPointers();
	else if (S3_TRIO64_FAMILY(gInfo.sharedInfo->chipType))
		Trio64_SetFunctionPointers();
	else if (S3_VIRGE_FAMILY(gInfo.sharedInfo->chipType))
		Virge_SetFunctionPointers();
	else
		return B_ERROR;		// undefined chip type code

	return B_OK;
}
示例#10
0
void
BDirectWindow::_InitData()
{
	fConnectionEnable = false;
	fIsFullScreen = false;
	fInDirectConnect = false;

	fInitStatus = 0;

	status_t status = B_ERROR;
	struct direct_window_sync_data syncData;

	fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA);
	if (fLink->FlushWithReply(status) == B_OK && status == B_OK)
		fLink->Read<direct_window_sync_data>(&syncData);

	if (status != B_OK)
		return;

#if DW_NEEDS_LOCKING
	fDirectLock = 0;
	fDirectLockCount = 0;
	fDirectLockOwner = -1;
	fDirectLockStack = NULL;
	fDirectSem = create_sem(0, "direct sem");
	if (fDirectSem > 0)
		fInitStatus |= DW_STATUS_SEM_CREATED;
#endif

	fSourceClippingArea = syncData.area;
	fDisableSem = syncData.disable_sem;
	fDisableSemAck = syncData.disable_sem_ack;

	fClonedClippingArea = clone_area("cloned direct area", (void**)&fBufferDesc,
		B_ANY_ADDRESS, B_READ_AREA, fSourceClippingArea);

	if (fClonedClippingArea > 0) {
		fInitStatus |= DW_STATUS_AREA_CLONED;

		fDirectDaemonId = spawn_thread(_daemon_thread, "direct daemon",
			B_DISPLAY_PRIORITY, this);

		if (fDirectDaemonId > 0) {
			fDaemonKiller = false;
			if (resume_thread(fDirectDaemonId) == B_OK)
				fInitStatus |= DW_STATUS_THREAD_STARTED;
			else
				kill_thread(fDirectDaemonId);
		}
	}
}
示例#11
0
static status_t
InitCommon(int fileDesc)
{
	// Initialization function used by primary and cloned accelerants.

	gInfo.deviceFileDesc = fileDesc;

	// Get area ID of shared data from driver.

	area_id sharedArea;
	status_t result = ioctl(gInfo.deviceFileDesc, ATI_GET_SHARED_DATA,
		&sharedArea, sizeof(sharedArea));
	if (result != B_OK)
		return result;

	gInfo.sharedInfoArea = clone_area("ATI shared info", (void**)&(gInfo.sharedInfo),
		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, sharedArea);
	if (gInfo.sharedInfoArea < 0)
		return gInfo.sharedInfoArea;	// sharedInfoArea has error code

	gInfo.regsArea = clone_area("ATI regs area", (void**)&(gInfo.regs),
		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gInfo.sharedInfo->regsArea);
	if (gInfo.regsArea < 0) {
		delete_area(gInfo.sharedInfoArea);
		return gInfo.regsArea;		// regsArea has error code
	}

	// Set pointers to various device specific functions.

	if (RAGE128_FAMILY(gInfo.sharedInfo->chipType))
		Rage128_SetFunctionPointers();
	else if (MACH64_FAMILY(gInfo.sharedInfo->chipType))
		Mach64_SetFunctionPointers();
	else
		return B_ERROR;		// undefined chip type code

	return B_OK;
}
示例#12
0
文件: arch_int.cpp 项目: RAZVOR/haiku
status_t
arch_int_init_post_vm(kernel_args *args)
{
	// create a read/write kernel area
	sVectorPageArea = create_area("vectorpage", (void **)&sVectorPageAddress,
		B_ANY_ADDRESS, VECTORPAGE_SIZE, B_FULL_LOCK,
		B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA);

	if (sVectorPageArea < 0)
		panic("vector page could not be created!");

	// clone it at a fixed address with user read/only permissions
	sUserVectorPageAddress = (addr_t*)USER_VECTOR_ADDR_HIGH;
	sUserVectorPageArea = clone_area("user_vectorpage",
		(void **)&sUserVectorPageAddress, B_EXACT_ADDRESS,
		B_READ_AREA | B_EXECUTE_AREA, sVectorPageArea);

	if (sUserVectorPageArea < 0)
		panic("user vector page @ %p could not be created (%lx)!", sVectorPageAddress, sUserVectorPageArea);

	// copy vectors into the newly created area
	memcpy(sVectorPageAddress, &_vectors_start, VECTORPAGE_SIZE);

	arm_vector_init();

	// see if high vectors are enabled
	if ((mmu_read_c1() & (1 << 13)) != 0)
		dprintf("High vectors already enabled\n");
	else {
		mmu_write_c1(mmu_read_c1() | (1 << 13));

		if ((mmu_read_c1() & (1 << 13)) == 0)
			dprintf("Unable to enable high vectors!\n");
		else
			dprintf("Enabled high vectors\n");
	}

	sPxaInterruptArea = map_physical_memory("pxa_intc", PXA_INTERRUPT_PHYS_BASE,
		PXA_INTERRUPT_SIZE, 0, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&sPxaInterruptBase);

	if (sPxaInterruptArea < 0)
		return sPxaInterruptArea;

	sPxaInterruptBase[PXA_ICMR] = 0;
	sPxaInterruptBase[PXA_ICMR2] = 0;

	return B_OK;
}
示例#13
0
static int vm_bang(void *str)
{
	for (int i = 0; i < 10; i++) {
		uint *addr;
		int area = create_area("original area", (void**) &addr, 0, 0x2000,
			AREA_NOT_WIRED, USER_READ | USER_WRITE);
		if (area < 0) {
			_serial_print("error creating original area\n");
			return 0;
		}
		
		unsigned var = rand();
		*addr = var;
		
		uint *clone_addr;
		int clone = clone_area("clone area", (void**) &clone_addr, 0,
			USER_WRITE | USER_READ, area);
		if (clone < 0) {
			_serial_print("error creating clone area\n");
			return 0;
		}
			
		if (*clone_addr != var) {
			_serial_print("clone failed to copy pages\n");
			return 0;
		}
		
		addr += 1024;
		clone_addr += 1024;
		*clone_addr = var;
		if (*addr != var) {
			_serial_print("page failed failed to be propigated\n");
			return 0;
		}
			
		for (int i = 0; i < 10; i++)
			resize_area(area, (i % 4) * PAGE_SIZE + PAGE_SIZE);
			
		delete_area(area);
		delete_area(clone);
	}

	printf("%s", (char*) str);
	atomic_add(&thread_count, -1);
	return 0;
}
示例#14
0
static status_t
clone_command_areas(net_area_info *localArea,net_command *command)
{
	int32 i;

	memset(localArea,0,sizeof(net_area_info) * MAX_NET_AREAS);

	for (i = 0;i < MAX_NET_AREAS;i++) {
		if (command->area[i].id <= 0)
			continue;

		localArea[i].id = clone_area("net connection",(void **)&localArea[i].offset,B_ANY_ADDRESS,
				B_READ_AREA | B_WRITE_AREA,command->area[i].id);
		if (localArea[i].id < B_OK)
			return localArea[i].id;
	}
	return B_OK;
}
示例#15
0
APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m,
                                         const char *filename,
                                         apr_pool_t *pool)
{
    area_info ai;
    thread_info ti;
    apr_shm_t *new_m;
    area_id deleteme = find_area(filename);

    if (deleteme == B_NAME_NOT_FOUND)
        return APR_EINVAL;

    new_m = (apr_shm_t*)apr_palloc(pool, sizeof(apr_shm_t*));
    if (new_m == NULL)
        return APR_ENOMEM;
    new_m->pool = pool;

    get_area_info(deleteme, &ai);
    get_thread_info(find_thread(NULL), &ti);

    if (ti.team != ai.team) {
        area_id narea;
        
        narea = clone_area(ai.name, &(ai.address), B_CLONE_ADDRESS,
                           B_READ_AREA|B_WRITE_AREA, ai.area);

        if (narea < B_OK)
            return narea;
            
        get_area_info(narea, &ai);
        new_m->aid = narea;
        new_m->memblock = ai.address;
        new_m->ptr = (void*)ai.address;
        new_m->avail = ai.size;
        new_m->reqsize = ai.size;
    }

    (*m) = new_m;
    
    return APR_SUCCESS;
}
示例#16
0
void
beos_backend_startup(void)
{
	char		nom[50];
	char		nvnom[50];
	area_info	inf;
	int32		cook = 0;

	/* Perform the remapping process */

	/* Loop in all our team areas */
	while (get_next_area_info(0, &cook, &inf) == B_OK)
	{
		strcpy(nom, inf.name);
		strcpy(nvnom, inf.name);
		nom[9] = 0;
		nvnom[5] = 'i';
		/* Is it a SYS V area ? */
		if (!strcmp(nom, "SYSV_IPC_"))
		{
			void	   *area_address;
			area_id		area_postmaster;

			/* Get the area address */
			area_address = inf.address;
			/* Destroy the bad area */
			delete_area(inf.area);
			/* Find the postmaster area */
			area_postmaster = find_area(inf.name);
			/* Compute new area name */
			sprintf(nvnom, "SYSV_IPC %d", area_postmaster);
			/* Clone it at the exact same address */
			clone_area(nvnom, &area_address, B_CLONE_ADDRESS, B_READ_AREA | B_WRITE_AREA, area_postmaster);
		}
	}

	/* remapping done release semaphore to allow other backend to startup */

	release_sem(beos_shm_sem);
}
示例#17
0
int main(void)
{
	area_id handler_buffer;
	if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) {
		printf("Can't find packet buffer\n");
		return 10;
	}
	if ((buffer_area = clone_area("local packet buffer", &net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) {
		printf("Can't clone packet buffer\n");
		return 10;
	}

	uint8 *p = net_buffer_ptr->ether_addr;
	printf("Ethernet address  : %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
	printf("read_sem          : %d\n", net_buffer_ptr->read_sem);
	printf("read_ofs          : %d\n", net_buffer_ptr->read_ofs);
	printf("read_packet_size  : %d\n", net_buffer_ptr->read_packet_size);
	printf("read_packet_count : %d\n", net_buffer_ptr->read_packet_count);
	printf("write_sem         : %d\n", net_buffer_ptr->write_sem);
	printf("write_ofs         : %d\n", net_buffer_ptr->write_ofs);
	printf("write_packet_size : %d\n", net_buffer_ptr->write_packet_size);
	printf("write_packet_count: %d\n", net_buffer_ptr->write_packet_count);

	printf("\nRead packets:\n");
	for (int i=0; i<READ_PACKET_COUNT; i++) {
		net_packet *p = &net_buffer_ptr->read[i];
		printf("cmd   : %08lx\n", p->cmd);
		printf("length: %d\n", p->length);
	}
	printf("\nWrite packets:\n");
	for (int i=0; i<WRITE_PACKET_COUNT; i++) {
		net_packet *p = &net_buffer_ptr->write[i];
		printf("cmd   : %08lx\n", p->cmd);
		printf("length: %d\n", p->length);
	}
	return 0;
}
示例#18
0
status_t
intel_clone_accelerant(void* info)
{
	CALLED();

	// create full device name
	char path[B_PATH_NAME_LENGTH];
	strcpy(path, "/dev/");
#ifdef __HAIKU__
	strlcat(path, (const char*)info, sizeof(path));
#else
	strcat(path, (const char*)info);
#endif

	int fd = open(path, B_READ_WRITE);
	if (fd < 0)
		return errno;

	status_t status = init_common(fd, true);
	if (status != B_OK)
		goto err1;

	// get read-only clone of supported display modes
	status = gInfo->mode_list_area = clone_area(
		"intel extreme cloned modes", (void**)&gInfo->mode_list,
		B_ANY_ADDRESS, B_READ_AREA, gInfo->shared_info->mode_list_area);
	if (status < B_OK)
		goto err2;

	return B_OK;

err2:
	uninit_common();
err1:
	close(fd);
	return status;
}
示例#19
0
/*! This is the common accelerant_info initializer. It is called by
	both, the first accelerant and all clones.
*/
static status_t
init_common(int device, bool isClone)
{
	// initialize global accelerant info structure

	gInfo = (accelerant_info*)malloc(sizeof(accelerant_info));

	if (gInfo == NULL)
		return B_NO_MEMORY;

	memset(gInfo, 0, sizeof(accelerant_info));

	// malloc memory for active display information
	for (uint32 id = 0; id < MAX_DISPLAY; id++) {
		gDisplay[id] = (display_info*)malloc(sizeof(display_info));
		if (gDisplay[id] == NULL)
			return B_NO_MEMORY;
		memset(gDisplay[id], 0, sizeof(display_info));

		gDisplay[id]->regs = (register_info*)malloc(sizeof(register_info));
		if (gDisplay[id]->regs == NULL)
			return B_NO_MEMORY;
		memset(gDisplay[id]->regs, 0, sizeof(register_info));
	}

	// malloc for possible physical card connectors
	for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
		gConnector[id] = (connector_info*)malloc(sizeof(connector_info));

		if (gConnector[id] == NULL)
			return B_NO_MEMORY;
		memset(gConnector[id], 0, sizeof(connector_info));
	}

	// malloc for card gpio pin information
	for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
		gGPIOInfo[id] = (gpio_info*)malloc(sizeof(gpio_info));

		if (gGPIOInfo[id] == NULL)
			return B_NO_MEMORY;
		memset(gGPIOInfo[id], 0, sizeof(gpio_info));
	}

	gInfo->is_clone = isClone;
	gInfo->device = device;

	gInfo->dpms_mode = B_DPMS_ON;
		// initial state

	// get basic info from driver

	radeon_get_private_data data;
	data.magic = RADEON_PRIVATE_DATA_MAGIC;

	if (ioctl(device, RADEON_GET_PRIVATE_DATA, &data,
			sizeof(radeon_get_private_data)) != 0) {
		free(gInfo);
		return B_ERROR;
	}

	AreaCloner sharedCloner;
	gInfo->shared_info_area = sharedCloner.Clone("radeon hd shared info",
		(void**)&gInfo->shared_info, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA,
		data.shared_info_area);
	status_t status = sharedCloner.InitCheck();
	if (status < B_OK) {
		free(gInfo);
		TRACE("%s, failed to create shared area\n", __func__);
		return status;
	}

	AreaCloner regsCloner;
	gInfo->regs_area = regsCloner.Clone("radeon hd regs",
		(void**)&gInfo->regs, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA,
		gInfo->shared_info->registers_area);
	status = regsCloner.InitCheck();
	if (status < B_OK) {
		free(gInfo);
		TRACE("%s, failed to create mmio area\n", __func__);
		return status;
	}

	gInfo->rom_area = clone_area("radeon hd AtomBIOS",
		(void**)&gInfo->rom, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA,
		gInfo->shared_info->rom_area);

	if (gInfo->rom_area < 0) {
		TRACE("%s: Clone of AtomBIOS failed!\n", __func__);
		gInfo->shared_info->has_rom = false;
	}

	if (gInfo->rom[0] != 0x55 || gInfo->rom[1] != 0xAA)
		TRACE("%s: didn't find a VGA bios in cloned region!\n", __func__);

	sharedCloner.Keep();
	regsCloner.Keep();

	return B_OK;
}
示例#20
0
status_t
SystemProfiler::Init()
{
	// clone the user area
	void* areaBase;
	fKernelArea = clone_area("profiling samples", &areaBase,
		B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
		fUserArea);
	if (fKernelArea < 0)
		return fKernelArea;

	// we need the memory locked
	status_t error = lock_memory(areaBase, fAreaSize, B_READ_DEVICE);
	if (error != B_OK) {
		delete_area(fKernelArea);
		fKernelArea = -1;
		return error;
	}

	// the buffer is ready for use
	fHeader = (system_profiler_buffer_header*)areaBase;
	fBufferBase = (uint8*)(fHeader + 1);
	fBufferCapacity = fAreaSize - (fBufferBase - (uint8*)areaBase);
	fHeader->start = 0;
	fHeader->size = 0;

	// allocate the wait object buffer and init the hash table
	if (fWaitObjectCount > 0) {
		fWaitObjectBuffer = new(std::nothrow) WaitObject[fWaitObjectCount];
		if (fWaitObjectBuffer == NULL)
			return B_NO_MEMORY;

		for (int32 i = 0; i < fWaitObjectCount; i++)
			fFreeWaitObjects.Add(fWaitObjectBuffer + i);

		error = fWaitObjectTable.Init(fWaitObjectCount * 3 / 2);
		if (error != B_OK)
			return error;
	}

	// start listening for notifications

	// teams
	NotificationManager& notificationManager
		= NotificationManager::Manager();
	if ((fFlags & B_SYSTEM_PROFILER_TEAM_EVENTS) != 0) {
		error = notificationManager.AddListener("teams",
			TEAM_ADDED | TEAM_REMOVED | TEAM_EXEC, *this);
		if (error != B_OK)
			return error;
		fTeamNotificationsRequested = true;
	}

	// threads
	if ((fFlags & B_SYSTEM_PROFILER_THREAD_EVENTS) != 0) {
		error = notificationManager.AddListener("threads",
			THREAD_ADDED | THREAD_REMOVED, *this);
		if (error != B_OK)
			return error;
		fThreadNotificationsRequested = true;
	}

	// images
	if ((fFlags & B_SYSTEM_PROFILER_IMAGE_EVENTS) != 0) {
		error = notificationManager.AddListener("images",
			IMAGE_ADDED | IMAGE_REMOVED, *this);
		if (error != B_OK)
			return error;
		fImageNotificationsRequested = true;
	}

	// I/O events
	if ((fFlags & B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS) != 0) {
		error = notificationManager.AddListener("I/O",
			IO_SCHEDULER_ADDED | IO_SCHEDULER_REMOVED
				| IO_SCHEDULER_REQUEST_SCHEDULED | IO_SCHEDULER_REQUEST_FINISHED
				| IO_SCHEDULER_OPERATION_STARTED
				| IO_SCHEDULER_OPERATION_FINISHED,
			*this);
		if (error != B_OK)
			return error;
		fIONotificationsRequested = true;
	}

	// We need to fill the buffer with the initial state of teams, threads,
	// and images.

	// teams
	if ((fFlags & B_SYSTEM_PROFILER_TEAM_EVENTS) != 0) {
		InterruptsSpinLocker locker(fLock);

		TeamListIterator iterator;
		while (Team* team = iterator.Next()) {
			locker.Unlock();

			bool added = _TeamAdded(team);

			// release the reference returned by the iterator
			team->ReleaseReference();

			if (!added)
				return B_BUFFER_OVERFLOW;

			locker.Lock();
		}

		fTeamNotificationsEnabled = true;
	}

	// images
	if ((fFlags & B_SYSTEM_PROFILER_IMAGE_EVENTS) != 0) {
		if (image_iterate_through_images(&_InitialImageIterator, this) != NULL)
			return B_BUFFER_OVERFLOW;
	}

	// threads
	if ((fFlags & B_SYSTEM_PROFILER_THREAD_EVENTS) != 0) {
		InterruptsSpinLocker locker(fLock);

		ThreadListIterator iterator;
		while (Thread* thread = iterator.Next()) {
			locker.Unlock();

			bool added = _ThreadAdded(thread);

			// release the reference returned by the iterator
			thread->ReleaseReference();

			if (!added)
				return B_BUFFER_OVERFLOW;

			locker.Lock();
		}

		fThreadNotificationsEnabled = true;
	}

	fProfilingActive = true;

	// start scheduler and wait object listening
	if ((fFlags & B_SYSTEM_PROFILER_SCHEDULING_EVENTS) != 0) {
		scheduler_add_listener(this);
		fSchedulerNotificationsRequested = true;

		InterruptsSpinLocker waitObjectLocker(gWaitObjectListenerLock);
		add_wait_object_listener(this);
		fWaitObjectNotificationsRequested = true;
		waitObjectLocker.Unlock();

		// fake schedule events for the initially running threads
		int32 cpuCount = smp_get_num_cpus();
		for (int32 i = 0; i < cpuCount; i++) {
			Thread* thread = gCPU[i].running_thread;
			if (thread != NULL)
				ThreadScheduled(thread, thread);
		}
	}

	// I/O scheduling
	if ((fFlags & B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS) != 0) {
		IOSchedulerRoster* roster = IOSchedulerRoster::Default();
		AutoLocker<IOSchedulerRoster> rosterLocker(roster);

		for (IOSchedulerList::ConstIterator it
				= roster->SchedulerList().GetIterator();
			IOScheduler* scheduler = it.Next();) {
			_IOSchedulerAdded(scheduler);
		}

		fIONotificationsEnabled = true;
	}

	// activate the profiling timers on all CPUs
	if ((fFlags & B_SYSTEM_PROFILER_SAMPLING_EVENTS) != 0)
		call_all_cpus(_InitTimers, this);

	return B_OK;
}
示例#21
0
image_id
beos_dl_open(char *filename)
{
	image_id	im;

	/* If a port doesn't exist, lauch support server */
	if ((beos_dl_port_in <= 0) || (beos_dl_port_out <= 0))
	{
		/* Create communication port */
		beos_dl_port_in = create_port(50, "beos_support_in");
		beos_dl_port_out = create_port(50, "beos_support_in");


		if ((beos_dl_port_in <= 0) || (beos_dl_port_out <= 0))
		{
			elog(WARNING, "error loading BeOS support server: could not create communication ports");
			return B_ERROR;
		}
		else
		{
			char		Cmd[4000];

			/* Build arg list */
			sprintf(Cmd, "%s -beossupportserver %d %d &", my_exec_path, (int) beos_dl_port_in, (int) beos_dl_port_out);

			/* Lauch process */
			system(Cmd);
		}
	}

	/* Add-on loading */

	/* Send command '1' (load) to the support server */
	write_port(beos_dl_port_in, 1, filename, strlen(filename) + 1);

	/* Read Object Id */
	read_port(beos_dl_port_out, &im, NULL, 0);

	/* Checking integrity */
	if (im < 0)
	{
		elog(WARNING, "could not load this add-on");
		return B_ERROR;
	}
	else
	{
		/* Map text and data segment in our address space */
		char		datas[4000];
		int32		area;
		int32		resu;
		void	   *add;

		/* read text segment id and address */
		read_port(beos_dl_port_out, &area, datas, 4000);
		read_port(beos_dl_port_out, (void *) &add, datas, 4000);
		/* map text segment in our address space */
		resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
		if (resu < 0)
		{
			/* If we can't map, we are in reload case */
			/* delete the mapping */
			resu = delete_area(area_for(add));
			/* Remap */
			resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
			if (resu < 0)
				elog(WARNING, "could not load this add-on: map text error");
		}

		/* read text segment id and address */
		read_port(beos_dl_port_out, &area, datas, 4000);
		read_port(beos_dl_port_out, (void *) &add, datas, 4000);
		/* map text segment in our address space */
		resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
		if (resu < 0)
		{
			/* If we can't map, we are in reload case */
			/* delete the mapping */
			resu = delete_area(area_for(add));
			/* Remap */
			resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
			if (resu < 0)
				elog(WARNING, "could not load this add-on: map data error");
		}

		return im;
	}
}
示例#22
0
/*
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];

	/* the data is the device name */
	/* Note: the R4 graphics driver kit is in error here (missing trailing '/') */
	strcpy(path, "/dev/");
	strcat(path, (const char *)data);
	/* open the device, the permissions aren't important */
	fd = open(path, B_READ_WRITE);
	if (fd < 0)
	{
		/* we can't use LOG because we didn't get the shared_info struct.. */
		char     fname[64];
		FILE    *myhand = NULL;

		sprintf (fname, "/boot/home/" DRIVER_PREFIX ".accelerant.0.log");
		myhand=fopen(fname,"a+");
		fprintf(myhand, "CLONE_ACCELERANT: couldn't open kerneldriver %s! Aborting.\n", path);
		fclose(myhand);

		/* abort with resultcode from open attempt on kerneldriver */
		result = errno;
		goto error0;
	}

	/* note that we're a clone accelerant */
	accelerantIsClone = 1;

	/* call the shared initialization code */
	result = init_common(fd);

	/* bail out if the common initialization failed */
	if (result != B_OK) goto error1;

	/* ensure that INIT_ACCELERANT is executed first (i.e. primary accelerant exists) */
	if (!(si->accelerant_in_use))
	{
		result = B_NOT_ALLOWED;
		goto error2;
	}

	/* get shared area for display modes */
	result = my_mode_list_area = clone_area(
		DRIVER_PREFIX " cloned display_modes",
		(void **)&my_mode_list,
		B_ANY_ADDRESS,
		B_READ_AREA,
		si->mode_area
	);
	if (result < B_OK) goto error2;

	/* all done */
	LOG(4,("CLONE_ACCELERANT: cloning was succesfull.\n"));

	result = B_OK;
	goto error0;

error2:
	/* free up the areas we cloned */
	uninit_common();
error1:
	/* close the device we opened */
	close(fd);
error0:
	return result;
}
示例#23
0
void
ServerApp::_HandleMessage(int32 code, const void* data, size_t size)
{
    TRACE("ServerApp::HandleMessage %#lx enter\n", code);
    switch (code) {
    case SERVER_CHANGE_FLAVOR_INSTANCES_COUNT:
    {
        const server_change_flavor_instances_count_request& request
            = *static_cast<
              const server_change_flavor_instances_count_request*>(data);
        server_change_flavor_instances_count_reply reply;
        status_t status = B_BAD_VALUE;

        if (request.delta == 1) {
            status = gNodeManager->IncrementFlavorInstancesCount(
                         request.add_on_id, request.flavor_id, request.team);
        } else if (request.delta == -1) {
            status = gNodeManager->DecrementFlavorInstancesCount(
                         request.add_on_id, request.flavor_id, request.team);
        }
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_RESCAN_DEFAULTS:
    {
        gNodeManager->RescanDefaultNodes();
        break;
    }

    case SERVER_REGISTER_APP:
    {
        const server_register_app_request& request = *static_cast<
                const server_register_app_request*>(data);
        server_register_app_reply reply;

        status_t status = gAppManager->RegisterTeam(request.team,
                          request.messenger);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_UNREGISTER_APP:
    {
        const server_unregister_app_request& request = *static_cast<
                const server_unregister_app_request*>(data);
        server_unregister_app_reply reply;

        status_t status = gAppManager->UnregisterTeam(request.team);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_ADD_ON_REF:
    {
        const server_get_add_on_ref_request& request = *static_cast<
                const server_get_add_on_ref_request*>(data);
        server_get_add_on_ref_reply reply;

        entry_ref ref;
        reply.result = gNodeManager->GetAddOnRef(request.add_on_id, &ref);
        reply.ref = ref;

        request.SendReply(reply.result, &reply, sizeof(reply));
        break;
    }

    case SERVER_NODE_ID_FOR:
    {
        const server_node_id_for_request& request
            = *static_cast<const server_node_id_for_request*>(data);
        server_node_id_for_reply reply;

        status_t status = gNodeManager->FindNodeID(request.port,
                          &reply.node_id);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_LIVE_NODE_INFO:
    {
        const server_get_live_node_info_request& request = *static_cast<
                const server_get_live_node_info_request*>(data);
        server_get_live_node_info_reply reply;

        status_t status = gNodeManager->GetLiveNodeInfo(request.node,
                          &reply.live_info);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_LIVE_NODES:
    {
        const server_get_live_nodes_request& request
            = *static_cast<const server_get_live_nodes_request*>(data);
        server_get_live_nodes_reply reply;
        LiveNodeList nodes;

        status_t status = gNodeManager->GetLiveNodes(nodes,
                          request.max_count,
                          request.has_input ? &request.input_format : NULL,
                          request.has_output ? &request.output_format : NULL,
                          request.has_name ? request.name : NULL, request.require_kinds);

        reply.count = nodes.size();
        reply.area = -1;

        live_node_info* infos = reply.live_info;
        area_id area = -1;

        if (reply.count > MAX_LIVE_INFO) {
            // We create an area here, and transfer it to the client
            size_t size = (reply.count * sizeof(live_node_info)
                           + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);

            area = create_area("get live nodes", (void**)&infos,
                               B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
            if (area < 0) {
                reply.area = area;
                reply.count = 0;
            }
        }

        for (int32 index = 0; index < reply.count; index++)
            infos[index] = nodes[index];

        if (area >= 0) {
            // transfer the area to the target team
            reply.area = _kern_transfer_area(area, &reply.address,
                                             B_ANY_ADDRESS, request.team);
            if (reply.area < 0) {
                delete_area(area);
                reply.count = 0;
            }
        }

        status = request.SendReply(status, &reply, sizeof(reply));
        if (status != B_OK && reply.area >= 0) {
            // if we couldn't send the message, delete the area
            delete_area(reply.area);
        }
        break;
    }

    case SERVER_GET_NODE_FOR:
    {
        const server_get_node_for_request& request
            = *static_cast<const server_get_node_for_request*>(data);
        server_get_node_for_reply reply;

        status_t status = gNodeManager->GetCloneForID(request.node_id,
                          request.team, &reply.clone);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_RELEASE_NODE:
    {
        const server_release_node_request& request
            = *static_cast<const server_release_node_request*>(data);
        server_release_node_reply reply;

        status_t status = gNodeManager->ReleaseNode(request.node,
                          request.team);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_RELEASE_NODE_ALL:
    {
        const server_release_node_request& request
            = *static_cast<const server_release_node_request*>(data);
        server_release_node_reply reply;

        status_t status = gNodeManager->ReleaseNodeAll(request.node.node);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_REGISTER_NODE:
    {
        const server_register_node_request& request
            = *static_cast<const server_register_node_request*>(data);
        server_register_node_reply reply;

        status_t status = gNodeManager->RegisterNode(request.add_on_id,
                          request.flavor_id, request.name, request.kinds, request.port,
                          request.team, &reply.node_id);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_UNREGISTER_NODE:
    {
        const server_unregister_node_request& request
            = *static_cast<const server_unregister_node_request*>(data);
        server_unregister_node_reply reply;

        status_t status = gNodeManager->UnregisterNode(request.node_id,
                          request.team, &reply.add_on_id, &reply.flavor_id);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_PUBLISH_INPUTS:
    {
        const server_publish_inputs_request& request
            = *static_cast<const server_publish_inputs_request*>(data);
        server_publish_inputs_reply reply;
        status_t status;

        if (request.count <= MAX_INPUTS) {
            status = gNodeManager->PublishInputs(request.node,
                                                 request.inputs, request.count);
        } else {
            media_input* inputs;
            area_id clone;
            clone = clone_area("media_inputs clone", (void**)&inputs,
                               B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, request.area);
            if (clone < B_OK) {
                ERROR("SERVER_PUBLISH_INPUTS: failed to clone area, "
                      "error %#lx\n", clone);
                status = clone;
            } else {
                status = gNodeManager->PublishInputs(request.node, inputs,
                                                     request.count);
                delete_area(clone);
            }
        }
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_PUBLISH_OUTPUTS:
    {
        const server_publish_outputs_request& request
            = *static_cast<const server_publish_outputs_request*>(data);
        server_publish_outputs_reply reply;
        status_t status;

        if (request.count <= MAX_OUTPUTS) {
            status = gNodeManager->PublishOutputs(request.node,
                                                  request.outputs, request.count);
        } else {
            media_output* outputs;
            area_id clone;
            clone = clone_area("media_outputs clone", (void**)&outputs,
                               B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, request.area);
            if (clone < B_OK) {
                ERROR("SERVER_PUBLISH_OUTPUTS: failed to clone area, "
                      "error %#lx\n", clone);
                status = clone;
            } else {
                status = gNodeManager->PublishOutputs(request.node, outputs,
                                                      request.count);
                delete_area(clone);
            }
        }
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_NODE:
    {
        const server_get_node_request& request
            = *static_cast<const server_get_node_request*>(data);
        server_get_node_reply reply;

        status_t status = gNodeManager->GetClone(request.type, request.team,
                          &reply.node, reply.input_name, &reply.input_id);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_SET_NODE:
    {
        const server_set_node_request& request
            = *static_cast<const server_set_node_request*>(data);
        server_set_node_reply reply;

        status_t status = gNodeManager->SetDefaultNode(request.type,
                          request.use_node ? &request.node : NULL,
                          request.use_dni ? &request.dni : NULL,
                          request.use_input ?  &request.input : NULL);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_DORMANT_NODE_FOR:
    {
        const server_get_dormant_node_for_request& request
            = *static_cast<const server_get_dormant_node_for_request*>(
                  data);
        server_get_dormant_node_for_reply reply;

        status_t status = gNodeManager->GetDormantNodeInfo(request.node,
                          &reply.node_info);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_INSTANCES_FOR:
    {
        const server_get_instances_for_request& request
            = *static_cast<const server_get_instances_for_request*>(data);
        server_get_instances_for_reply reply;

        status_t status = gNodeManager->GetInstances(request.add_on_id,
                          request.flavor_id, reply.node_id, &reply.count,
                          min_c(request.max_count, MAX_NODE_ID));
        if (reply.count == MAX_NODE_ID
                && request.max_count > MAX_NODE_ID) {
            // TODO: might be fixed by using an area
            PRINT(1, "Warning: SERVER_GET_INSTANCES_FOR: returning "
                  "possibly truncated list of node id's\n");
        }
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_REGISTER_ADD_ON:
    {
        const server_register_add_on_request& request = *static_cast<
                const server_register_add_on_request*>(data);
        server_register_add_on_reply reply;

        gNodeManager->RegisterAddOn(request.ref, &reply.add_on_id);
        request.SendReply(B_OK, &reply, sizeof(reply));
        break;
    }

    case SERVER_UNREGISTER_ADD_ON:
    {
        const server_unregister_add_on_command& request = *static_cast<
                const server_unregister_add_on_command*>(data);
        gNodeManager->UnregisterAddOn(request.add_on_id);
        break;
    }

    case SERVER_REGISTER_DORMANT_NODE:
    {
        const server_register_dormant_node_command& command
            = *static_cast<const server_register_dormant_node_command*>(
                  data);
        if (command.purge_id > 0)
            gNodeManager->InvalidateDormantFlavorInfo(command.purge_id);

        dormant_flavor_info dormantFlavorInfo;
        status_t status = dormantFlavorInfo.Unflatten(command.type,
                          command.flattened_data, command.flattened_size);
        if (status == B_OK)
            gNodeManager->AddDormantFlavorInfo(dormantFlavorInfo);
        break;
    }

    case SERVER_GET_DORMANT_NODES:
    {
        const server_get_dormant_nodes_request& request
            = *static_cast<const server_get_dormant_nodes_request*>(data);

        server_get_dormant_nodes_reply reply;
        reply.count = request.max_count;

        dormant_node_info* infos
            = new(std::nothrow) dormant_node_info[reply.count];
        if (infos != NULL) {
            reply.result = gNodeManager->GetDormantNodes(infos,
                           &reply.count,
                           request.has_input ? &request.input_format : NULL,
                           request.has_output ? &request.output_format : NULL,
                           request.has_name ? request.name : NULL,
                           request.require_kinds, request.deny_kinds);
        } else
            reply.result = B_NO_MEMORY;

        if (reply.result != B_OK)
            reply.count = 0;

        request.SendReply(reply.result, &reply, sizeof(reply));
        if (reply.count > 0) {
            write_port(request.reply_port, 0, infos,
                       reply.count * sizeof(dormant_node_info));
        }
        delete[] infos;
        break;
    }

    case SERVER_GET_DORMANT_FLAVOR_INFO:
    {
        const server_get_dormant_flavor_info_request& request
            = *static_cast<const server_get_dormant_flavor_info_request*>(
                  data);
        dormant_flavor_info dormantFlavorInfo;

        status_t status = gNodeManager->GetDormantFlavorInfoFor(
                              request.add_on_id, request.flavor_id, &dormantFlavorInfo);
        if (status != B_OK) {
            server_get_dormant_flavor_info_reply reply;
            reply.result = status;
            request.SendReply(reply.result, &reply, sizeof(reply));
        } else {
            size_t replySize
                = sizeof(server_get_dormant_flavor_info_reply)
                  + dormantFlavorInfo.FlattenedSize();
            server_get_dormant_flavor_info_reply* reply
                = (server_get_dormant_flavor_info_reply*)malloc(
                      replySize);
            if (reply != NULL) {
                reply->type = dormantFlavorInfo.TypeCode();
                reply->flattened_size = dormantFlavorInfo.FlattenedSize();
                reply->result = dormantFlavorInfo.Flatten(
                                    reply->flattened_data, reply->flattened_size);

                request.SendReply(reply->result, reply, replySize);
                free(reply);
            } else {
                server_get_dormant_flavor_info_reply reply;
                reply.result = B_NO_MEMORY;
                request.SendReply(reply.result, &reply, sizeof(reply));
            }
        }
        break;
    }

    case SERVER_SET_NODE_CREATOR:
    {
        const server_set_node_creator_request& request
            = *static_cast<const server_set_node_creator_request*>(data);
        server_set_node_creator_reply reply;
        status_t status = gNodeManager->SetNodeCreator(request.node,
                          request.creator);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_SHARED_BUFFER_AREA:
    {
        const server_get_shared_buffer_area_request& request
            = *static_cast<const server_get_shared_buffer_area_request*>(
                  data);
        server_get_shared_buffer_area_reply reply;

        reply.area = gBufferManager->SharedBufferListArea();
        request.SendReply(reply.area >= 0 ? B_OK : reply.area, &reply,
                          sizeof(reply));
        break;
    }

    case SERVER_REGISTER_BUFFER:
    {
        const server_register_buffer_request& request
            = *static_cast<const server_register_buffer_request*>(data);
        server_register_buffer_reply reply;
        status_t status;

        if (request.info.buffer == 0) {
            reply.info = request.info;
            // size, offset, flags, area is kept
            // get a new beuffer id into reply.info.buffer
            status = gBufferManager->RegisterBuffer(request.team,
                                                    request.info.size, request.info.flags,
                                                    request.info.offset, request.info.area,
                                                    &reply.info.buffer);
        } else {
            reply.info = request.info; // buffer id is kept
            status = gBufferManager->RegisterBuffer(request.team,
                                                    request.info.buffer, &reply.info.size, &reply.info.flags,
                                                    &reply.info.offset, &reply.info.area);
        }
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_UNREGISTER_BUFFER:
    {
        const server_unregister_buffer_command& request = *static_cast<
                const server_unregister_buffer_command*>(data);

        gBufferManager->UnregisterBuffer(request.team, request.buffer_id);
        break;
    }

    case SERVER_GET_MEDIA_FILE_TYPES:
    {
        const server_get_media_types_request& request
            = *static_cast<const server_get_media_types_request*>(data);

        server_get_media_types_reply reply;
        area_id area = gMediaFilesManager->GetTypesArea(reply.count);
        if (area >= 0) {
            // transfer the area to the target team
            reply.area = _kern_transfer_area(area, &reply.address,
                                             B_ANY_ADDRESS, request.team);
            if (reply.area < 0) {
                delete_area(area);
                reply.area = B_ERROR;
                reply.count = 0;
            }
        }

        status_t status = request.SendReply(
                              reply.area < 0 ? reply.area : B_OK, &reply, sizeof(reply));
        if (status != B_OK) {
            // if we couldn't send the message, delete the area
            delete_area(reply.area);
        }
        break;
    }

    case SERVER_GET_MEDIA_FILE_ITEMS:
    {
        const server_get_media_items_request& request
            = *static_cast<const server_get_media_items_request*>(data);

        server_get_media_items_reply reply;
        area_id area = gMediaFilesManager->GetItemsArea(request.type,
                       reply.count);
        if (area >= 0) {
            // transfer the area to the target team
            reply.area = _kern_transfer_area(area, &reply.address,
                                             B_ANY_ADDRESS, request.team);
            if (reply.area < 0) {
                delete_area(area);
                reply.area = B_ERROR;
                reply.count = 0;
            }
        } else
            reply.area = area;

        status_t status = request.SendReply(
                              reply.area < 0 ? reply.area : B_OK, &reply, sizeof(reply));
        if (status != B_OK) {
            // if we couldn't send the message, delete the area
            delete_area(reply.area);
        }
        break;
    }

    case SERVER_GET_REF_FOR:
    {
        const server_get_ref_for_request& request
            = *static_cast<const server_get_ref_for_request*>(data);
        server_get_ref_for_reply reply;
        entry_ref* ref;

        status_t status = gMediaFilesManager->GetRefFor(request.type,
                          request.item, &ref);
        if (status == B_OK)
            reply.ref = *ref;

        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_SET_REF_FOR:
    {
        const server_set_ref_for_request& request
            = *static_cast<const server_set_ref_for_request*>(data);
        server_set_ref_for_reply reply;
        entry_ref ref = request.ref;

        status_t status = gMediaFilesManager->SetRefFor(request.type,
                          request.item, ref);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_INVALIDATE_MEDIA_ITEM:
    {
        const server_invalidate_item_request& request
            = *static_cast<const server_invalidate_item_request*>(data);
        server_invalidate_item_reply reply;

        status_t status = gMediaFilesManager->InvalidateItem(request.type,
                          request.item);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_REMOVE_MEDIA_ITEM:
    {
        const server_remove_media_item_request& request
            = *static_cast<const server_remove_media_item_request*>(data);
        server_remove_media_item_reply reply;

        status_t status = gMediaFilesManager->RemoveItem(request.type,
                          request.item);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_ITEM_AUDIO_GAIN:
    {
        const server_get_item_audio_gain_request& request
            = *static_cast<const server_get_item_audio_gain_request*>(data);
        server_get_item_audio_gain_reply reply;

        status_t status = gMediaFilesManager->GetAudioGainFor(request.type,
                          request.item, &reply.gain);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_SET_ITEM_AUDIO_GAIN:
    {
        const server_set_item_audio_gain_request& request
            = *static_cast<const server_set_item_audio_gain_request*>(data);
        server_set_ref_for_reply reply;

        status_t status = gMediaFilesManager->SetAudioGainFor(request.type,
                          request.item, request.gain);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_READERS:
    {
        const server_get_readers_request& request
            = *static_cast<const server_get_readers_request*>(data);
        server_get_readers_reply reply;

        status_t status = gAddOnManager->GetReaders(reply.ref, &reply.count,
                          MAX_READERS);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_DECODER_FOR_FORMAT:
    {
        const server_get_decoder_for_format_request& request
            = *static_cast<
              const server_get_decoder_for_format_request*>(data);
        server_get_decoder_for_format_reply reply;

        status_t status = gAddOnManager->GetDecoderForFormat(&reply.ref,
                          request.format);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_WRITER_FOR_FORMAT_FAMILY:
    {
        const server_get_writer_request& request
            = *static_cast<const server_get_writer_request*>(data);
        server_get_writer_reply reply;

        status_t status = gAddOnManager->GetWriter(&reply.ref,
                          request.internal_id);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_FILE_FORMAT_FOR_COOKIE:
    {
        const server_get_file_format_request& request
            = *static_cast<const server_get_file_format_request*>(data);
        server_get_file_format_reply reply;

        status_t status = gAddOnManager->GetFileFormat(&reply.file_format,
                          request.cookie);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_CODEC_INFO_FOR_COOKIE:
    {
        const server_get_codec_info_request& request
            = *static_cast<const server_get_codec_info_request*>(data);
        server_get_codec_info_reply reply;

        status_t status = gAddOnManager->GetCodecInfo(&reply.codec_info,
                          &reply.format_family, &reply.input_format,
                          &reply.output_format, request.cookie);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    case SERVER_GET_ENCODER_FOR_CODEC_INFO:
    {
        const server_get_encoder_for_codec_info_request& request
            = *static_cast<
              const server_get_encoder_for_codec_info_request*>(data);
        server_get_encoder_for_codec_info_reply reply;
        status_t status = gAddOnManager->GetEncoder(&reply.ref, request.id);
        request.SendReply(status, &reply, sizeof(reply));
        break;
    }

    default:
        printf("media_server: received unknown message code %#08lx\n",
               code);
    }
    TRACE("ServerApp::HandleMessage %#lx leave\n", code);
}
示例#24
0
文件: Requests.cpp 项目: DonCN/haiku
	template<typename R> status_t operator()(R* request)
	{
		// check the request buffer size
		if (fRequestBufferSize < (int32)sizeof(R))
			RETURN_ERROR(B_BAD_DATA);
		// no need to relocate the addresses of a reply that indicates an error
		if (is_error_reply(request)) {
			fSuccess = true;
			return B_OK;
		}
		// get the address infos
		AddressInfo infos[MAX_REQUEST_ADDRESS_COUNT];
		int32 count = 0;
		status_t error = request->GetAddressInfos(infos, &count);
		if (error != B_OK)
			RETURN_ERROR(error);
		// check and relocate the addresses
		for (int32 i = 0; i < count; i++) {
			// check
			Address* address = infos[i].address;
			int32 size = address->GetSize();
			int32 offset = address->GetOffset();
//PRINT(("  relocating address: area: %ld, offset: %ld, size: %ld...\n",
//address->GetArea(), offset, size));
			if (offset < 0 || size < 0 || size > infos[i].max_size)
				RETURN_ERROR(B_BAD_DATA);
			if ((infos[i].flags & ADDRESS_NOT_NULL) && size == 0)
				RETURN_ERROR(B_BAD_DATA);
			// relocate
			area_id area = address->GetArea();
			if (area < 0) {
				// data in the buffer itself
				if (offset == 0 && size == 0) {
//PRINT(("    -> relocated address: NULL\n"));
					address->SetRelocatedAddress(NULL);
				} else {
					if (offset < (int32)sizeof(R)
						|| offset + size > fRequestBufferSize) {
						RETURN_ERROR(B_BAD_DATA);
					}
//PRINT(("    -> relocated address: %p\n", (uint8*)request + offset));
					address->SetRelocatedAddress((uint8*)request + offset);
				}
			} else {
				// clone the area
				void* data;
				area = clone_area("cloned request data", &data,
#ifdef _KERNEL_MODE
					B_ANY_KERNEL_ADDRESS,
#else
					B_ANY_ADDRESS,
#endif
					B_READ_AREA, area);
				if (area < 0)
					RETURN_ERROR(area);
				fAreas[(*fAreaCount)++] = area;
				// check offset and size
				area_info areaInfo;
				error = get_area_info(area, &areaInfo);
				if (error != B_OK)
					RETURN_ERROR(error);
				if (offset + size > (int32)areaInfo.size)
					RETURN_ERROR(B_BAD_DATA);
//PRINT(("    -> relocated address: %p\n", (uint8*)data + offset));
				address->SetRelocatedAddress((uint8*)data + offset);
			}
		}
		// finally let the request check its integrity
		error = request->Check();
		if (error != B_OK)
			RETURN_ERROR(error);
		fSuccess = true;
//PRINT(("RequestRelocator done: success\n"));
		return B_OK;
	}
示例#25
0
文件: usb.cpp 项目: MaddTheSane/haiku
static int32
bus_std_ops(int32 op, ...)
{
	switch (op) {
		case B_MODULE_INIT: {
			TRACE_MODULE("init\n");
			if (gUSBStack)
				return B_OK;

#ifdef HAIKU_TARGET_PLATFORM_BEOS
			// This code is to handle plain R5 (non-BONE) where the same module
			// gets loaded multiple times (once for each exported module
			// interface, the USB v2 and v3 API in our case). We don't want to
			// ever create multiple stacks however, so we "share" the same stack
			// for both modules by storing it's address in a shared area.
			void *address = NULL;
			area_id shared = find_area("shared usb stack");
			if (shared >= B_OK && clone_area("usb stack clone", &address,
				B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, shared) >= B_OK) {
				gUSBStack = *((Stack **)address);
				TRACE_MODULE("found shared stack at %p\n", gUSBStack);
				return B_OK;
			}
#endif

#ifdef TRACE_USB
			set_dprintf_enabled(true);
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
			load_driver_symbols("usb");
#endif
#endif
			Stack *stack = new(std::nothrow) Stack();
			TRACE_MODULE("usb_module: stack created %p\n", stack);
			if (!stack)
				return B_NO_MEMORY;

			if (stack->InitCheck() != B_OK) {
				delete stack;
				return ENODEV;
			}

			gUSBStack = stack;

#ifdef HAIKU_TARGET_PLATFORM_HAIKU
			add_debugger_command("get_usb_pipe_for_id",
				&debug_get_pipe_for_id,
				"Gets the config for a USB pipe");
#elif HAIKU_TARGET_PLATFORM_BEOS
			// Plain R5 workaround, see comment above.
			shared = create_area("shared usb stack", &address,
				B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_NO_LOCK,
				B_KERNEL_WRITE_AREA);
			if (shared >= B_OK)
				*((Stack **)address) = gUSBStack;
#endif
			break;
		}

		case B_MODULE_UNINIT:
			TRACE_MODULE("uninit\n");
			delete gUSBStack;
			gUSBStack = NULL;

#ifdef HAIKU_TARGET_PLATFORM_HAIKU
			remove_debugger_command("get_usb_pipe_for_id",
				&debug_get_pipe_for_id);
#endif
			break;

		default:
			return EINVAL;
	}

	return B_OK;
}
示例#26
0
void 
ServerApp::HandleMessage(int32 code, void *data, size_t size)
{
	status_t rv;
	TRACE("ServerApp::HandleMessage %#lx enter\n", code);
	switch (code) {
		case SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT:
		{
			const server_change_addon_flavor_instances_count_request *request = reinterpret_cast<const server_change_addon_flavor_instances_count_request *>(data);
			server_change_addon_flavor_instances_count_reply reply;
			ASSERT(request->delta == 1 || request->delta == -1);
			if (request->delta == 1)
				rv = gNodeManager->IncrementAddonFlavorInstancesCount(request->addonid,	request->flavorid, request->team);
			else
				rv = gNodeManager->DecrementAddonFlavorInstancesCount(request->addonid,	request->flavorid, request->team);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_RESCAN_DEFAULTS:
		{
			gNodeManager->RescanDefaultNodes();
			break;
		}
	
		case SERVER_REGISTER_ADDONSERVER:
		{
			const server_register_addonserver_request *request = reinterpret_cast<const server_register_addonserver_request *>(data);
			server_register_addonserver_reply reply;
			rv = gAppManager->RegisterAddonServer(request->team);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_REGISTER_APP:
		{
			const server_register_app_request *request = reinterpret_cast<const server_register_app_request *>(data);
			server_register_app_reply reply;
			rv = gAppManager->RegisterTeam(request->team, request->messenger);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_UNREGISTER_APP:
		{
			const server_unregister_app_request *request = reinterpret_cast<const server_unregister_app_request *>(data);
			server_unregister_app_reply reply;
			rv = gAppManager->UnregisterTeam(request->team);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
	
		case SERVER_GET_MEDIAADDON_REF:
		{
			server_get_mediaaddon_ref_request *msg = (server_get_mediaaddon_ref_request *)data;
			server_get_mediaaddon_ref_reply reply;
			entry_ref tempref;
			reply.result = gNodeManager->GetAddonRef(&tempref, msg->addonid);
			reply.ref = tempref;
			write_port(msg->reply_port, 0, &reply, sizeof(reply));
			break;
		}

		case SERVER_NODE_ID_FOR:
		{
			const server_node_id_for_request *request = reinterpret_cast<const server_node_id_for_request *>(data);
			server_node_id_for_reply reply;
			rv = gNodeManager->FindNodeId(&reply.nodeid, request->port);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_GET_LIVE_NODE_INFO:
		{
			const server_get_live_node_info_request *request = reinterpret_cast<const server_get_live_node_info_request *>(data);
			server_get_live_node_info_reply reply;
			rv = gNodeManager->GetLiveNodeInfo(&reply.live_info, request->node);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_GET_LIVE_NODES:
		{
			const server_get_live_nodes_request *request = reinterpret_cast<const server_get_live_nodes_request *>(data);
			server_get_live_nodes_reply reply;
			Stack<live_node_info> livenodes;
			rv = gNodeManager->GetLiveNodes(
					&livenodes,
					request->maxcount,
					request->has_input ? &request->inputformat : NULL,
					request->has_output ? &request->outputformat : NULL,
					request->has_name ? request->name : NULL,
					request->require_kinds);
			reply.count = livenodes.CountItems();
			if (reply.count <= MAX_LIVE_INFO) {
				for (int32 index = 0; index < reply.count; index++)
					livenodes.Pop(&reply.live_info[index]);
				reply.area = -1;
			} else {
				// we create an area here, and pass it to the library, where it will be deleted.
				live_node_info *start_addr;
				size_t size;
				size = ((reply.count * sizeof(live_node_info)) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
				reply.area = create_area("get live nodes", reinterpret_cast<void **>(&start_addr), B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
				if (reply.area < B_OK) {
					ERROR("SERVER_GET_LIVE_NODES: failed to create area, error %#lx\n", reply.area);
					reply.count = 0;
					rv = B_ERROR;
				} else {
					for (int32 index = 0; index < reply.count; index++)
						livenodes.Pop(&start_addr[index]);
				}
			}
			rv = request->SendReply(rv, &reply, sizeof(reply));
			if (rv != B_OK)
				delete_area(reply.area); // if we couldn't send the message, delete the area
			break;
		}
		
		case SERVER_GET_NODE_FOR:
		{
			const server_get_node_for_request *request = reinterpret_cast<const server_get_node_for_request *>(data);
			server_get_node_for_reply reply;
			rv = gNodeManager->GetCloneForId(&reply.clone, request->nodeid, request->team);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_RELEASE_NODE:
		{
			const server_release_node_request *request = reinterpret_cast<const server_release_node_request *>(data);
			server_release_node_reply reply;
			rv = gNodeManager->ReleaseNode(request->node, request->team);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_REGISTER_NODE:
		{
			const server_register_node_request *request = reinterpret_cast<const server_register_node_request *>(data);
			server_register_node_reply reply;
			rv = gNodeManager->RegisterNode(&reply.nodeid, request->addon_id, request->addon_flavor_id, request->name, request->kinds, request->port, request->team);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_UNREGISTER_NODE:
		{
			const server_unregister_node_request *request = reinterpret_cast<const server_unregister_node_request *>(data);
			server_unregister_node_reply reply;
			rv = gNodeManager->UnregisterNode(&reply.addonid, &reply.flavorid, request->nodeid, request->team);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_PUBLISH_INPUTS:
		{
			const server_publish_inputs_request *request = reinterpret_cast<const server_publish_inputs_request *>(data);
			server_publish_inputs_reply reply;
			if (request->count <= MAX_INPUTS) {
				rv = gNodeManager->PublishInputs(request->node, request->inputs, request->count);
			} else {
				media_input *inputs;
				area_id clone;
				clone = clone_area("media_inputs clone", reinterpret_cast<void **>(&inputs), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, request->area);
				if (clone < B_OK) {
					ERROR("SERVER_PUBLISH_INPUTS: failed to clone area, error %#lx\n", clone);
					rv = B_ERROR;
				} else {
					rv = gNodeManager->PublishInputs(request->node, inputs, request->count);
					delete_area(clone);
				}
			}
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_PUBLISH_OUTPUTS:
		{
			const server_publish_outputs_request *request = reinterpret_cast<const server_publish_outputs_request *>(data);
			server_publish_outputs_reply reply;
			if (request->count <= MAX_OUTPUTS) {
				rv = gNodeManager->PublishOutputs(request->node, request->outputs, request->count);
			} else {
				media_output *outputs;
				area_id clone;
				clone = clone_area("media_outputs clone", reinterpret_cast<void **>(&outputs), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, request->area);
				if (clone < B_OK) {
					ERROR("SERVER_PUBLISH_OUTPUTS: failed to clone area, error %#lx\n", clone);
					rv = B_ERROR;
				} else {
					rv = gNodeManager->PublishOutputs(request->node, outputs, request->count);
					delete_area(clone);
				}
			}
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_GET_NODE:
		{
			const server_get_node_request *request = reinterpret_cast<const server_get_node_request *>(data);
			server_get_node_reply reply;
			rv = gNodeManager->GetClone(&reply.node, reply.input_name, &reply.input_id, request->type, request->team);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_SET_NODE:
		{
			const server_set_node_request *request = reinterpret_cast<const server_set_node_request *>(data);
			server_set_node_reply reply;
			rv = gNodeManager->SetDefaultNode(request->type, request->use_node ? &request->node : NULL, request->use_dni ? &request->dni : NULL, request->use_input ?  &request->input : NULL);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_GET_DORMANT_NODE_FOR:
		{
			const server_get_dormant_node_for_request *request = reinterpret_cast<const server_get_dormant_node_for_request *>(data);
			server_get_dormant_node_for_reply reply;
			rv = gNodeManager->GetDormantNodeInfo(&reply.node_info, request->node);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_GET_INSTANCES_FOR:
		{
			const server_get_instances_for_request *request = reinterpret_cast<const server_get_instances_for_request *>(data);
			server_get_instances_for_reply reply;
			rv = gNodeManager->GetInstances(reply.node_id, &reply.count, min_c(request->maxcount, MAX_NODE_ID), request->addon_id, request->addon_flavor_id);
			if (reply.count == MAX_NODE_ID && request->maxcount > MAX_NODE_ID) { // XXX might be fixed by using an area
				PRINT(1, "Warning: SERVER_GET_INSTANCES_FOR: returning possibly truncated list of node id's\n");
			}
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_REGISTER_MEDIAADDON:
		{
			server_register_mediaaddon_request *msg = (server_register_mediaaddon_request *)data;
			server_register_mediaaddon_reply reply;
			gNodeManager->RegisterAddon(msg->ref, &reply.addonid);
			write_port(msg->reply_port, 0, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_UNREGISTER_MEDIAADDON:
		{
			server_unregister_mediaaddon_command *msg = (server_unregister_mediaaddon_command *)data;
			gNodeManager->UnregisterAddon(msg->addonid);
			break;
		}
		
		case SERVER_REGISTER_DORMANT_NODE:
		{
			xfer_server_register_dormant_node *msg = (xfer_server_register_dormant_node *)data;
			dormant_flavor_info dfi;
			if (msg->purge_id > 0)
				gNodeManager->InvalidateDormantFlavorInfo(msg->purge_id);
			rv = dfi.Unflatten(msg->dfi_type, &(msg->dfi), msg->dfi_size);
			ASSERT(rv == B_OK);
			gNodeManager->AddDormantFlavorInfo(dfi);	
			break;
		}
		
		case SERVER_GET_DORMANT_NODES:
		{
			xfer_server_get_dormant_nodes *msg = (xfer_server_get_dormant_nodes *)data;
			xfer_server_get_dormant_nodes_reply reply;
			dormant_node_info * infos = new dormant_node_info[msg->maxcount];
			reply.count = msg->maxcount;
			reply.result = gNodeManager->GetDormantNodes(
				infos, 
				&reply.count,
				msg->has_input ? &msg->inputformat : NULL,
				msg->has_output ? &msg->outputformat : NULL,
				msg->has_name ? msg->name : NULL,
				msg->require_kinds,
				msg->deny_kinds);
			if (reply.result != B_OK)
				reply.count = 0;
			write_port(msg->reply_port, 0, &reply, sizeof(reply));
			if (reply.count > 0)
				write_port(msg->reply_port, 0, infos, reply.count * sizeof(dormant_node_info));
			delete [] infos;
			break;
		}
		
		case SERVER_GET_DORMANT_FLAVOR_INFO:
		{
			xfer_server_get_dormant_flavor_info *msg = (xfer_server_get_dormant_flavor_info *)data;
			dormant_flavor_info dfi;
			status_t rv;

			rv = gNodeManager->GetDormantFlavorInfoFor(msg->addon, msg->flavor_id, &dfi);
			if (rv != B_OK) {
				xfer_server_get_dormant_flavor_info_reply reply;
				reply.result = rv;
				write_port(msg->reply_port, 0, &reply, sizeof(reply));
			} else {
				xfer_server_get_dormant_flavor_info_reply *reply;
				int replysize;
				replysize = sizeof(xfer_server_get_dormant_flavor_info_reply) + dfi.FlattenedSize();
				reply = (xfer_server_get_dormant_flavor_info_reply *)malloc(replysize);

				reply->dfi_size = dfi.FlattenedSize();
				reply->dfi_type = dfi.TypeCode();
				reply->result = dfi.Flatten(reply->dfi, reply->dfi_size);
				write_port(msg->reply_port, 0, reply, replysize);
				free(reply);
			}
			break;
		}

		case SERVER_SET_NODE_CREATOR:
		{
			const server_set_node_creator_request *request = reinterpret_cast<const server_set_node_creator_request *>(data);
			server_set_node_creator_reply reply;
			rv = gNodeManager->SetNodeCreator(request->node, request->creator);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_GET_SHARED_BUFFER_AREA:
		{
			const server_get_shared_buffer_area_request *request = reinterpret_cast<const server_get_shared_buffer_area_request *>(data);
			server_get_shared_buffer_area_reply reply;

			reply.area = gBufferManager->SharedBufferListID();
			request->SendReply(B_OK, &reply, sizeof(reply));
			break;
		}
				
		case SERVER_REGISTER_BUFFER:
		{
			const server_register_buffer_request *request = reinterpret_cast<const server_register_buffer_request *>(data);
			server_register_buffer_reply reply;
			status_t status;
			if (request->info.buffer == 0) {
				reply.info = request->info; //size, offset, flags, area is kept
				// get a new beuffer id into reply.info.buffer 
				status = gBufferManager->RegisterBuffer(request->team, request->info.size, request->info.flags, request->info.offset, request->info.area, &reply.info.buffer);
			} else {
				reply.info = request->info; //buffer id is kept
				status = gBufferManager->RegisterBuffer(request->team, request->info.buffer, &reply.info.size, &reply.info.flags, &reply.info.offset, &reply.info.area);
			}
			request->SendReply(status, &reply, sizeof(reply));
			break;
		}

		case SERVER_UNREGISTER_BUFFER:
		{
			const server_unregister_buffer_command *cmd = reinterpret_cast<const server_unregister_buffer_command *>(data);

			gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid);
			break;
		}
		
		case SERVER_REWINDTYPES:
		{
			const server_rewindtypes_request *request = reinterpret_cast<const server_rewindtypes_request *>(data);
			server_rewindtypes_reply reply;
			
			BString **types = NULL;
			
			rv = gMMediaFilesManager->RewindTypes(
					&types, &reply.count);
			if(reply.count>0) {
				// we create an area here, and pass it to the library, where it will be deleted.
				char *start_addr;
				size_t size = ((reply.count * B_MEDIA_NAME_LENGTH) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
				reply.area = create_area("rewind types", reinterpret_cast<void **>(&start_addr), B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
				if (reply.area < B_OK) {
					ERROR("SERVER_REWINDTYPES: failed to create area, error %s\n", strerror(reply.area));
					reply.count = 0;
					rv = B_ERROR;
				} else {
					for (int32 index = 0; index < reply.count; index++)
						strncpy(start_addr + B_MEDIA_NAME_LENGTH * index, types[index]->String(), B_MEDIA_NAME_LENGTH);
				}
			}
			
			delete types;
			
			rv = request->SendReply(rv, &reply, sizeof(reply));
			if (rv != B_OK)
				delete_area(reply.area); // if we couldn't send the message, delete the area
			break;
		}
		
		case SERVER_REWINDREFS:
		{
			const server_rewindrefs_request *request = reinterpret_cast<const server_rewindrefs_request *>(data);
			server_rewindrefs_reply reply;
			
			BString **items = NULL;
			
			rv = gMMediaFilesManager->RewindRefs(request->type,
					&items, &reply.count);
			// we create an area here, and pass it to the library, where it will be deleted.
			if(reply.count>0) {
				char *start_addr;
				size_t size = ((reply.count * B_MEDIA_NAME_LENGTH) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
				reply.area = create_area("rewind refs", reinterpret_cast<void **>(&start_addr), B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
				if (reply.area < B_OK) {
					ERROR("SERVER_REWINDREFS: failed to create area, error %s\n", strerror(reply.area));
					reply.count = 0;
					rv = B_ERROR;
				} else {
					for (int32 index = 0; index < reply.count; index++)
						strncpy(start_addr + B_MEDIA_NAME_LENGTH * index, items[index]->String(), B_MEDIA_NAME_LENGTH);
				}
			}
			
			delete items;

			rv = request->SendReply(rv, &reply, sizeof(reply));
			if (rv != B_OK)
				delete_area(reply.area); // if we couldn't send the message, delete the area
			break;
		}
		
		case SERVER_GETREFFOR:
		{
			const server_getreffor_request *request = reinterpret_cast<const server_getreffor_request *>(data);
			server_getreffor_reply reply;
			entry_ref *ref;

			rv = gMMediaFilesManager->GetRefFor(request->type, request->item, &ref);
			if(rv==B_OK) {
				reply.ref = *ref;
			}
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_SETREFFOR:
		{
			const server_setreffor_request *request = reinterpret_cast<const server_setreffor_request *>(data);
			server_setreffor_reply reply;
			entry_ref ref = request->ref;
			
			rv = gMMediaFilesManager->SetRefFor(request->type, request->item, ref);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_REMOVEREFFOR:
		{
			const server_removereffor_request *request = reinterpret_cast<const server_removereffor_request *>(data);
			server_removereffor_reply reply;
			entry_ref ref = request->ref;
			
			rv = gMMediaFilesManager->RemoveRefFor(request->type, request->item, ref);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		case SERVER_REMOVEITEM:
		{
			const server_removeitem_request *request = reinterpret_cast<const server_removeitem_request *>(data);
			server_removeitem_reply reply;

			rv = gMMediaFilesManager->RemoveItem(request->type, request->item);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_GET_READERS:
		{
			const server_get_readers_request *request = reinterpret_cast<const server_get_readers_request *>(data);
			server_get_readers_reply reply;
			rv = gAddOnManager->GetReaders(reply.ref, &reply.count, MAX_READERS);
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}

		case SERVER_GET_DECODER_FOR_FORMAT:
		{
			const server_get_decoder_for_format_request *request = reinterpret_cast<const server_get_decoder_for_format_request *>(data);
			server_get_decoder_for_format_reply reply;
			rv = gAddOnManager->GetDecoderForFormat(&reply.ref, request->format);						 
			request->SendReply(rv, &reply, sizeof(reply));
			break;
		}
		
		default:
			printf("media_server: received unknown message code %#08lx\n",code);
	}
	TRACE("ServerApp::HandleMessage %#lx leave\n", code);
}
示例#27
0
int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
                              unsigned fProt, size_t offSub, size_t cbSub)
{
    PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
    PRTR0MEMOBJHAIKU pMemHaiku;
    area_id area = -1;
    void *pvMap = pvFixed;
    uint32 uAddrSpec = B_EXACT_ADDRESS;
    uint32 fProtect = 0;
    int rc = VERR_MAP_FAILED;
    AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
    AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
#if 0
    /** @todo r=ramshankar: Wrong format specifiers, fix later! */
    dprintf("%s(%p, %p, %p, %d, %x, %u, %u)\n", __FUNCTION__, ppMem, pMemToMap, pvFixed, uAlignment,
            fProt, offSub, cbSub);
#endif
    /* Check that the specified alignment is supported. */
    if (uAlignment > PAGE_SIZE)
        return VERR_NOT_SUPPORTED;

    /* We can't map anything to the first page, sorry. */
    if (pvFixed == 0)
        return VERR_NOT_SUPPORTED;

    if (fProt & RTMEM_PROT_READ)
        fProtect |= B_KERNEL_READ_AREA;
    if (fProt & RTMEM_PROT_WRITE)
        fProtect |= B_KERNEL_WRITE_AREA;

    /*
     * Either the object we map has an area associated with, which we can clone,
     * or it's a physical address range which we must map.
     */
    if (pMemToMapHaiku->AreaId > -1)
    {
        if (pvFixed == (void *)-1)
            uAddrSpec = B_ANY_KERNEL_ADDRESS;

        rc = area = clone_area("IPRT R0MemObj MapKernel", &pvMap, uAddrSpec, fProtect, pMemToMapHaiku->AreaId);
        LogFlow(("rtR0MemObjNativeMapKernel: clone_area uAddrSpec=%d fProtect=%x AreaId=%d rc=%d\n", uAddrSpec, fProtect,
                 pMemToMapHaiku->AreaId, rc));
    }
    else if (pMemToMapHaiku->Core.enmType == RTR0MEMOBJTYPE_PHYS)
    {
        /* map_physical_memory() won't let you choose where. */
        if (pvFixed != (void *)-1)
            return VERR_NOT_SUPPORTED;
        uAddrSpec = B_ANY_KERNEL_ADDRESS;

        rc = area = map_physical_memory("IPRT R0MemObj MapKernelPhys", (phys_addr_t)pMemToMapHaiku->Core.u.Phys.PhysBase,
                                        pMemToMapHaiku->Core.cb, uAddrSpec, fProtect, &pvMap);
    }
    else
        return VERR_NOT_SUPPORTED;

    if (rc >= B_OK)
    {
        /* Create the object. */
        pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), RTR0MEMOBJTYPE_MAPPING, pvMap,
                    pMemToMapHaiku->Core.cb);
        if (RT_UNLIKELY(!pMemHaiku))
            return VERR_NO_MEMORY;

        pMemHaiku->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
        pMemHaiku->Core.pv = pvMap;
        pMemHaiku->AreaId = area;
        *ppMem = &pMemHaiku->Core;
        return VINF_SUCCESS;
    }
    rc = VERR_MAP_FAILED;

    /** @todo finish the implementation. */

    rtR0MemObjDelete(&pMemHaiku->Core);
    return rc;
}