/** Handle ac97 driver ioctl. * \par Description: * Handle ac97 driver ioctl. * \param psDriver - AC97 driver structure. * \param nCommand - Command. * \param pArgs - Args. * \param bFromKernel - Ioctl from kernel. * \author Arno Klenke *****************************************************************************/ status_t ac97_ioctl( AC97AudioDriver_s* psDriver, uint32 nCommand, void *pArgs, bool bFromKernel ) { switch( nCommand ) { case AC97_GET_CODEC_INFO: memcpy_to_user( pArgs, psDriver, sizeof( AC97AudioDriver_s ) ); break; case AC97_WAIT: { AC97RegOp_s sOp; memcpy_from_user( &sOp, pArgs, sizeof( AC97RegOp_s ) ); psDriver->pfWait( psDriver->pDriverData, sOp.nCodec ); } break; case AC97_READ: { AC97RegOp_s sOp; memcpy_from_user( &sOp, pArgs, sizeof( AC97RegOp_s ) ); sOp.nVal = ac97_read( psDriver, sOp.nCodec, sOp.nReg ); memcpy_to_user( pArgs, &sOp, sizeof( AC97RegOp_s ) ); } break; case AC97_WRITE: { AC97RegOp_s sOp; memcpy_from_user( &sOp, pArgs, sizeof( AC97RegOp_s ) ); ac97_write( psDriver, sOp.nCodec, sOp.nReg, sOp.nVal ); } break; default: return( -EINVAL ); } return( 0 ); }
status_t gfx_ioctl( void *pNode, void *pCookie, uint32 nCommand, void *pArgs, bool bFromKernel ) { struct gfx_node *psNode = pNode; int nError = 0; switch ( nCommand ) { case IOCTL_GET_APPSERVER_DRIVER: memcpy_to_user( pArgs, APPSERVER_DRIVER, strlen( APPSERVER_DRIVER ) ); break; case PCI_GFX_GET_PCI_INFO: memcpy_to_user( pArgs, &psNode->sInfo, sizeof( PCI_Info_s ) ); break; case PCI_GFX_READ_PCI_CONFIG: { struct gfx_pci_config sConfig; PCI_bus_s *psBus = get_busmanager( PCI_BUS_NAME, PCI_BUS_VERSION ); memcpy_from_user( &sConfig, pArgs, sizeof( struct gfx_pci_config ) ); if( psBus == NULL ) { nError = -ENODEV; } else { sConfig.m_nValue = psBus->read_pci_config( sConfig.m_nBus, sConfig.m_nDevice, sConfig.m_nFunction, sConfig.m_nOffset, sConfig.m_nSize ); memcpy_to_user( pArgs, &sConfig, sizeof( struct gfx_pci_config ) ); } } break; case PCI_GFX_WRITE_PCI_CONFIG: { struct gfx_pci_config sConfig; PCI_bus_s *psBus = get_busmanager( PCI_BUS_NAME, PCI_BUS_VERSION ); memcpy_from_user( &sConfig, pArgs, sizeof( struct gfx_pci_config ) ); if( psBus == NULL ) { nError = -ENODEV; } else { int nVal = psBus->write_pci_config( sConfig.m_nBus, sConfig.m_nDevice, sConfig.m_nFunction, sConfig.m_nOffset, sConfig.m_nSize, sConfig.m_nValue ); sConfig.m_nValue = nVal; memcpy_to_user( pArgs, &sConfig, sizeof( struct gfx_pci_config ) ); } } break; default: nError = -ENOIOCTLCMD; } return ( nError ); }
status_t sys_get_next_port_info( port_info * psInfo ) { port_info sInfo; MsgPort_s *psPort; port_id hPort; int nError; if ( memcpy_from_user( &hPort, &psInfo->pi_port_id, sizeof( hPort ) ) < 0 ) { return ( -EFAULT ); } lock_mutex( g_hPortListSema, true ); hPort = MArray_GetNextIndex( &g_sMsgPorts, hPort ); psPort = get_port_from_handle( hPort ); if ( psPort == NULL ) { nError = 0; goto error; } do_get_port_info( psPort, &sInfo ); nError = 1; if ( memcpy_to_user( psInfo, &sInfo, sizeof( sInfo ) ) < 0 ) { nError = -EFAULT; } error: unlock_mutex( g_hPortListSema ); return ( nError ); }
status_t sys_get_port_info( port_id hPort, port_info * psInfo ) { port_info sInfo; MsgPort_s *psPort; int nError; lock_mutex( g_hPortListSema, true ); if ( hPort == -1 ) { hPort = MArray_GetNextIndex( &g_sMsgPorts, -1 ); } psPort = get_port_from_handle( hPort ); if ( psPort == NULL ) { nError = -EINVAL; goto error; } do_get_port_info( psPort, &sInfo ); nError = 0; if ( memcpy_to_user( psInfo, &sInfo, sizeof( sInfo ) ) < 0 ) { nError = -EFAULT; } error: unlock_mutex( g_hPortListSema ); return ( nError ); }
static int get_modem_info( SerPort_s* psPort, uint32* value, bool bFromKernel ) { uint8 control, status; uint32 result; uint32 flags; control = psPort->sp_nMCR; flags = spinlock_disable( &g_sSPinLock ); status = ser_in( psPort, UART_MSR ); spinunlock_enable( &g_sSPinLock, flags ); result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) #ifdef TIOCM_OUT1 | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) #endif | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); if ( bFromKernel ) { *value = result; return( 0 ); } else { return( memcpy_to_user( value, &result, sizeof(uint32) ) ); } }
/* Function to help map the argument and environment strings, to their * final location. */ int remap(int argc, char *argv[], char *new_argv[], char new_argbuf[], int arg_lens[]) { int offset = 0; char *temp_argv[argc + 1]; for(int i = 0; i < argc; i++) { if (memcpy_to_user(p, new_argbuf + offset, argv[i], arg_lens[i])) return -1; temp_argv[i] = new_argbuf + offset; offset += arg_lens[i]; } temp_argv[argc] = NULL; if (memcpy_to_user(p, new_argv, temp_argv, sizeof(temp_argv))) return -1; return offset; }
uint syscall_readline(char *cmd, uint buf_size) { char localbuf[256]; readline(localbuf, 256); localbuf[buf_size] = 0; memcpy_to_user(cmd, localbuf, buf_size); return 0; }
/* Same as above, but sets errno */ int memcpy_to_user_errno(struct proc *p, void *dst, const void *src, int len) { int error = memcpy_to_user(p, dst, src, len); if (unlikely(error < 0)) set_errno(-error); return error; }
static int get_lsr_info( SerPort_s* psPort, uint32* value, bool bFromKernel ) { uint8 status; uint32 result; uint32 flags; flags = spinlock_disable( &g_sSPinLock ); status = ser_in( psPort, UART_LSR ); spinunlock_enable( &g_sSPinLock, flags ); result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); if ( bFromKernel ) { *value = result; return( 0 ); } else { return( memcpy_to_user( value, &result, sizeof(uint32) ) ); } }
static status_t do_get_msg_x( bool bFromKernel, port_id hPort, uint32 *pnCode, void *pBuffer, int nSize, bigtime_t nTimeOut ) { MsgPort_s *psPort = NULL; MessageNode_s *psNode; int nRealSize; int nError; lock_mutex( g_hPortListSema, true ); psPort = get_port_from_handle( hPort ); if ( NULL == psPort ) { printk( "get_msg_x() attempt to receive message from invalid port %d\n", hPort ); nError = -EINVAL; goto error1; } again: if ( psPort->mp_psFirstMsg == NULL ) { sem_id hSyncSema; // We take a backup here since the port might get deleted // when we release the g_hPortListSema semaphore. // If the port is deleted so is the semaphore and lock_semaphore() // will return an error. It's then very important not to // touch the port again until we has revalidated the port-handle. hSyncSema = psPort->mp_hSyncSema; unlock_mutex( g_hPortListSema ); nError = lock_semaphore( hSyncSema, 0, nTimeOut ); lock_mutex( g_hPortListSema, true ); if ( nError < 0 ) { goto error1; } // We must revalidate the handle after unlocking g_hPortListSema psPort = get_port_from_handle( hPort ); if ( NULL == psPort ) { nError = -EINVAL; printk( "Message port %d deleted while we were wating for a message\n", hPort ); goto error1; } } else { if ( lock_semaphore( psPort->mp_hSyncSema, SEM_NOSIG, 0LL ) < 0 ) { printk( "get_msg_x() failed to lock mp_hSyncSema even though there were pending messages\n" ); } } psNode = psPort->mp_psFirstMsg; if ( psNode == NULL ) { printk( "get_msg_x() locked mp_hSyncSema even though the message list was empty on port %d\n", hPort ); goto again; } nRealSize = min( nSize, psNode->mn_nSize ); psPort->mp_psFirstMsg = psNode->mn_psNext; if ( NULL == psPort->mp_psFirstMsg ) { psPort->mp_psLastMsg = NULL; } psPort->mp_nCount--; if ( NULL != pBuffer ) { if( bFromKernel ) memcpy( pBuffer, psNode + 1, nRealSize ); else memcpy_to_user( pBuffer, psNode + 1, nRealSize ); } if ( NULL != pnCode ) { if( bFromKernel ) *pnCode = psNode->mn_nCode; else memcpy_to_user( pnCode, &psNode->mn_nCode, sizeof( psNode->mn_nCode ) ); } nError = ( nSize >= psNode->mn_nSize ) ? 0 : -E2BIG; kfree( psNode ); error1: unlock_mutex( g_hPortListSema ); return ( nError ); }
status_t do_get_system_info( system_info * psInfo, int nVersion, bool bFromKernel ) { status_t nRet; switch ( nVersion ) { /* Versions 1 and 2 removed in 0.6.6 */ case 3: { system_info_v3 sInfo; int i; sInfo.nBootTime = g_sSysBase.ex_nBootTime; /* time of boot (# usec since 1/1/70) */ sInfo.nCPUCount = g_nActiveCPUCount; sInfo.nCPUType = g_asProcessorDescs[g_nBootCPU].pi_nFeatures; sInfo.nMaxPages = g_sSysBase.ex_nTotalPageCount; /* total # physical pages */ sInfo.nFreePages = atomic_read( &g_sSysBase.ex_nFreePageCount ); /* Number of free physical pages */ sInfo.nCommitedPages = g_sSysBase.ex_nCommitPageCount; /* Total number of allocated pages */ sInfo.nKernelMemSize = atomic_read( &g_sSysBase.ex_nKernelMemSize ); sInfo.nPageFaults = atomic_read( &g_sSysBase.ex_nPageFaultCount ); /* Number of page faults */ sInfo.nUsedSemaphores = atomic_read( &g_sSysBase.ex_nSemaphoreCount ); /* Number of semaphores in use */ sInfo.nUsedPorts = atomic_read( &g_sSysBase.ex_nMessagePortCount ); /* Number of message ports in use */ sInfo.nUsedThreads = atomic_read( &g_sSysBase.ex_nThreadCount ); /* Number of living threads */ sInfo.nUsedProcesses = atomic_read( &g_sSysBase.ex_nProcessCount ); /* Number of living processes */ sInfo.nLoadedImageCount = atomic_read( &g_sSysBase.ex_nLoadedImageCount ); sInfo.nImageInstanceCount = atomic_read( &g_sSysBase.ex_nImageInstanceCount ); sInfo.nOpenFileCount = atomic_read( &g_sSysBase.ex_nOpenFileCount ); sInfo.nAllocatedInodes = atomic_read( &g_sSysBase.ex_nAllocatedInodeCount ); sInfo.nLoadedInodes = atomic_read( &g_sSysBase.ex_nLoadedInodeCount ); sInfo.nUsedInodes = atomic_read( &g_sSysBase.ex_nUsedInodeCount ); sInfo.nBlockCacheSize = atomic_read( &g_sSysBase.ex_nBlockCacheSize ); sInfo.nDirtyCacheSize = atomic_read( &g_sSysBase.ex_nDirtyCacheSize ); sInfo.nLockedCacheBlocks = g_sSysBase.ex_nLockedCacheBlocks; strcpy( sInfo.zKernelName, g_pzKernelName ); /* Name of kernel image */ strcpy( sInfo.zKernelBuildDate, g_pzBuildData ); /* Date of kernel built */ strcpy( sInfo.zKernelBuildTime, g_pzBuildTime ); /* Time of kernel built */ strcpy( sInfo.zKernelCpuArch, g_pzCpuArch ); /* CPU this kernel is running on */ strcpy( sInfo.zKernelSystem, g_pzSystem ); /* OS name (E.g. "AtheOS") */ for ( i = 0; i < g_nActiveCPUCount; ++i ) { int nID = logical_to_physical_cpu_id( i ); sInfo.asCPUInfo[i].nCoreSpeed = g_asProcessorDescs[nID].pi_nCoreSpeed; sInfo.asCPUInfo[i].nBusSpeed = g_asProcessorDescs[nID].pi_nBusSpeed; sInfo.asCPUInfo[i].nActiveTime = get_system_time(); sInfo.asCPUInfo[i].nActiveTime -= g_asProcessorDescs[nID].pi_psIdleThread->tr_nCPUTime; } sInfo.nKernelVersion = g_nKernelVersion; if( bFromKernel ) nRet = memcpy( psInfo, &sInfo, sizeof( sInfo ) ); else nRet = memcpy_to_user( psInfo, &sInfo, sizeof( sInfo ) ); return nRet; } case 4: { system_info sInfo; int i; int nArgc; char** apzArgv; char* pzPos; sInfo.nBootTime = g_sSysBase.ex_nBootTime; /* time of boot (# usec since 1/1/70) */ sInfo.nCPUCount = g_nActiveCPUCount; sInfo.nCPUType = g_asProcessorDescs[g_nBootCPU].pi_nFeatures; sInfo.nMaxPages = g_sSysBase.ex_nTotalPageCount; /* total # physical pages */ sInfo.nFreePages = atomic_read( &g_sSysBase.ex_nFreePageCount ); /* Number of free physical pages */ sInfo.nCommitedPages = g_sSysBase.ex_nCommitPageCount; /* Total number of allocated pages */ sInfo.nKernelMemSize = atomic_read( &g_sSysBase.ex_nKernelMemSize ); sInfo.nPageFaults = atomic_read( &g_sSysBase.ex_nPageFaultCount ); /* Number of page faults */ sInfo.nUsedSemaphores = atomic_read( &g_sSysBase.ex_nSemaphoreCount ); /* Number of semaphores in use */ sInfo.nUsedPorts = atomic_read( &g_sSysBase.ex_nMessagePortCount ); /* Number of message ports in use */ sInfo.nUsedThreads = atomic_read( &g_sSysBase.ex_nThreadCount ); /* Number of living threads */ sInfo.nUsedProcesses = atomic_read( &g_sSysBase.ex_nProcessCount ); /* Number of living processes */ sInfo.nLoadedImageCount = atomic_read( &g_sSysBase.ex_nLoadedImageCount ); sInfo.nImageInstanceCount = atomic_read( &g_sSysBase.ex_nImageInstanceCount ); sInfo.nOpenFileCount = atomic_read( &g_sSysBase.ex_nOpenFileCount ); sInfo.nAllocatedInodes = atomic_read( &g_sSysBase.ex_nAllocatedInodeCount ); sInfo.nLoadedInodes = atomic_read( &g_sSysBase.ex_nLoadedInodeCount ); sInfo.nUsedInodes = atomic_read( &g_sSysBase.ex_nUsedInodeCount ); sInfo.nBlockCacheSize = atomic_read( &g_sSysBase.ex_nBlockCacheSize ); sInfo.nDirtyCacheSize = atomic_read( &g_sSysBase.ex_nDirtyCacheSize ); sInfo.nLockedCacheBlocks = g_sSysBase.ex_nLockedCacheBlocks; strcpy( sInfo.zKernelName, g_pzKernelName ); /* Name of kernel image */ strcpy( sInfo.zKernelBuildDate, g_pzBuildData ); /* Date of kernel built */ strcpy( sInfo.zKernelBuildTime, g_pzBuildTime ); /* Time of kernel built */ strcpy( sInfo.zKernelCpuArch, g_pzCpuArch ); /* CPU this kernel is running on */ strcpy( sInfo.zKernelSystem, g_pzSystem ); /* OS name (E.g. "AtheOS") */ /* Kernel boot parameters */ get_kernel_arguments( &nArgc, &apzArgv ); pzPos = sInfo.zKernelBootParams; for( i = 0; i < nArgc; i++ ) { strcpy( pzPos, apzArgv[i] ); pzPos += strlen( apzArgv[i] ); *pzPos++ = ' '; } *(--pzPos) = 0; for ( i = 0; i < g_nActiveCPUCount; ++i ) { int nID = logical_to_physical_cpu_id( i ); sInfo.asCPUInfo[i].nCoreSpeed = g_asProcessorDescs[nID].pi_nCoreSpeed; sInfo.asCPUInfo[i].nBusSpeed = g_asProcessorDescs[nID].pi_nBusSpeed; sInfo.asCPUInfo[i].nActiveTime = get_system_time(); sInfo.asCPUInfo[i].nActiveTime -= g_asProcessorDescs[nID].pi_psIdleThread->tr_nCPUTime; } sInfo.nKernelVersion = g_nKernelVersion; if( bFromKernel ) nRet = memcpy( psInfo, &sInfo, sizeof( sInfo ) ); else nRet = memcpy_to_user( psInfo, &sInfo, sizeof( sInfo ) ); return nRet; } default: printk( "Error: sys_get_system_info() invalid version %d\n", nVersion ); return ( -EINVAL ); } }