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; }
/* 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 **)®s, 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; }
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; }
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; }
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; }
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; }
/* 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(); }
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; }
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); } } }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
/*! 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; }
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; }
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; } }
/* 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; }
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); }
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; }
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; }
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); }
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; }