Пример #1
0
/** 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 );
}
Пример #2
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 );
}
Пример #3
0
static int
format_trapframe(struct hw_trapframe *hw_tf, char* buf, int bufsz)
{
    // slightly hackish way to read out the instruction that faulted.
    // not guaranteed to be right 100% of the time
    uint32_t insn;
    if(!(current && !memcpy_from_user(current,&insn,(void*)hw_tf->epc,4)))
        insn = -1;

    int len = snprintf(buf,bufsz,"TRAP frame at %p on core %d\n",
                       hw_tf, core_id());
    static const char* regnames[] = {
        "z ", "ra", "s0", "s1", "s2", "s3", "s4", "s5",
        "s6", "s7", "s8", "s9", "sA", "sB", "sp", "tp",
        "v0", "v1", "a0", "a1", "a2", "a3", "a4", "a5",
        "a6", "a7", "a8", "a9", "aA", "aB", "aC", "aD"
    };

    hw_tf->gpr[0] = 0;

    for(int i = 0; i < 32; i+=4)
    {
        for(int j = 0; j < 4; j++)
            len += snprintf(buf+len, bufsz-len,
                            "%s %016lx%c", regnames[i+j], hw_tf->gpr[i+j],
                            j < 3 ? ' ' : '\n');
    }
    len += snprintf(buf+len, bufsz-len,
                    "sr %016lx pc %016lx va %016lx insn       %08x\n",
                    hw_tf->sr, hw_tf->epc, hw_tf->badvaddr, insn);

    buf[bufsz-1] = 0;
    return len;
}
Пример #4
0
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 );
}
Пример #5
0
// Системный вызов syscall_nputs_color
// Предоставляет процессам функцию nputs_color
// Параметры те же, что и обычно. Строка не длиннее 255 символов.
// Возвращает количество выведенных символов.
//
// FIXME: Нужно проверять наличие доступа к пользовательской
// памяти. Предупреждать GP, PF (в смысле выхода за выделенную память.
uint syscall_nputs_color(char *s, uint n, uchar attr)
{
   uchar localbuf[256];
   memcpy_from_user(localbuf, s, MIN(n, 256));
   nputs_color(localbuf, MIN(n, 256), attr);
   return MIN(n, 256);
}
Пример #6
0
static int set_modem_info( SerPort_s* psPort, int cmd, uint32* value, bool bFromKernel )
{
    int error;
    unsigned int arg;
    unsigned long flags;

    if ( bFromKernel ) {
	arg = *value;
	error = 0;
    } else {
	error = memcpy_from_user( &arg, value, sizeof(uint32) );
    }
    if (error)
	return error;
  
    switch (cmd) {
	case TIOCMBIS: 
	    if (arg & TIOCM_RTS)
		psPort->sp_nMCR |= UART_MCR_RTS;
	    if (arg & TIOCM_DTR)
		psPort->sp_nMCR |= UART_MCR_DTR;
#ifdef TIOCM_OUT1
	    if (arg & TIOCM_OUT1)
		psPort->sp_nMCR |= UART_MCR_OUT1;
	    if (arg & TIOCM_OUT2)
		psPort->sp_nMCR |= UART_MCR_OUT2;
#endif
	    break;
	case TIOCMBIC:
	    if (arg & TIOCM_RTS)
		psPort->sp_nMCR &= ~UART_MCR_RTS;
	    if (arg & TIOCM_DTR)
		psPort->sp_nMCR &= ~UART_MCR_DTR;
#ifdef TIOCM_OUT1
	    if (arg & TIOCM_OUT1)
		psPort->sp_nMCR &= ~UART_MCR_OUT1;
	    if (arg & TIOCM_OUT2)
		psPort->sp_nMCR &= ~UART_MCR_OUT2;
#endif
	    break;
	case TIOCMSET:
	    psPort->sp_nMCR = ((psPort->sp_nMCR & ~(UART_MCR_RTS |
#ifdef TIOCM_OUT1
						    UART_MCR_OUT1 |UART_MCR_OUT2 |
#endif
						    UART_MCR_DTR)) | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
#ifdef TIOCM_OUT1
			       | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
			       | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
#endif
			       | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
	    break;
	default:
	    return -EINVAL;
    }
    flags = spinlock_disable( &g_sSPinLock );
    ser_out( psPort, UART_MCR, psPort->sp_nMCR );
    spinunlock_enable( &g_sSPinLock, flags );
    return 0;
}
Пример #7
0
/**
 * Duplicate a string from user memory.
 *
 * Allocates a buffer large enough and copies across a string from user memory.
 * The allocation is not made using MM_WAIT, as there is no length limit and
 * therefore the length could be too large to fit in memory. Use of
 * strndup_from_user() is preferred to this.
 *
 * @param src		Location to copy from.
 * @param destp		Pointer to location in which to store address of
 *			destination buffer.
 *
 * @return		Status code describing result of the operation.
 *			Returns STATUS_INVALID_ARG if the string is
 *			zero-length.
 */
status_t strdup_from_user(const void *src, char **destp) {
	status_t ret;
	size_t len;
	char *d;

	ret = strlen_user(src, &len);
	if(ret != STATUS_SUCCESS) {
		return ret;
	} else if(len == 0) {
		return STATUS_INVALID_ARG;
	}

	d = kmalloc(len + 1, MM_USER);
	if(!d)
		return STATUS_NO_MEMORY;

	ret = memcpy_from_user(d, src, len);
	if(ret != STATUS_SUCCESS) {
		kfree(d);
		return ret;
	}
	d[len] = 0;
	*destp = d;
	return STATUS_SUCCESS;
}
Пример #8
0
/* Same as above, but sets errno */
int memcpy_from_user_errno(struct proc *p, void *dst, const void *src, int len)
{
	int error = memcpy_from_user(p, dst, src, len);

	if (unlikely(error < 0))
		set_errno(-error);

	return error;
}
Пример #9
0
/* Creates a buffer (kmalloc) and safely copies into it from va.  Can return an
 * error code.  Check its response with IS_ERR().  Must be paired with
 * user_memdup_free() if this succeeded. */
void *user_memdup(struct proc *p, const void *va, int len)
{
	void* kva = NULL;
	if (len < 0 || (kva = kmalloc(len, 0)) == NULL)
		return ERR_PTR(-ENOMEM);
	if (memcpy_from_user(p, kva, va, len)) {
		kfree(kva);
		return ERR_PTR(-EFAULT);
	}
	return kva;
}
Пример #10
0
int fd_write(int uid, int fd, const void *buf, uint32_t count) {
	uint8_t buff[512];
	int i, j, cnt;

	for (j = 0; (j<<9) < count; j++) {
		cnt = (count-(j<<9)>512)?512:(count-(j<<9));
		memcpy_from_user(buff, buf, cnt);
		kconsole_write(buff, cnt);
	}

	return count;
}
Пример #11
0
static int set_termios( SerPort_s* psPort, struct termios* psInfo )
{
    struct termios sTermios;
    int	 nError;

    nError = memcpy_from_user( &sTermios, psInfo, sizeof( sTermios ) );

    if ( nError < 0 ) {
	return( nError );
    }
  
    if ( (psPort->sp_sTermios.c_cflag & CBAUD) != (sTermios.c_cflag & CBAUD) ) {
	uint32 nFlg;
	switch( sTermios.c_cflag & CBAUD )
	{
	    case B0:		psPort->sp_nBaudRate = 0;
	    case B50:		psPort->sp_nBaudRate = 50;
	    case B75:		psPort->sp_nBaudRate = 75;
	    case B110:	psPort->sp_nBaudRate = 110;
	    case B134:	psPort->sp_nBaudRate = 134;
	    case B150:	psPort->sp_nBaudRate = 150;
	    case B200:	psPort->sp_nBaudRate = 200;
	    case B300:	psPort->sp_nBaudRate = 300;
	    case B600:	psPort->sp_nBaudRate = 600;
	    case B1200:	psPort->sp_nBaudRate = 1200;
	    case B1800:	psPort->sp_nBaudRate = 1800;
	    case B2400:	psPort->sp_nBaudRate = 2400;
	    case B4800:	psPort->sp_nBaudRate = 4800;
	    case B9600:	psPort->sp_nBaudRate = 9600;
	    case B19200:	psPort->sp_nBaudRate = 19200;
	    case B38400:	psPort->sp_nBaudRate = 38400;
	    case B57600:	psPort->sp_nBaudRate = 57600;
	    case B115200:	psPort->sp_nBaudRate = 115200;
//      case B230400:	psPort->sp_nBaudRate = 230400;
//      case B460800:	psPort->sp_nBaudRate = 460800;
	    default:
		printk( "serial: set_termios() invalid baudrate %08x\n", sTermios.c_cflag & CBAUD );
		return( -EINVAL );
	}
	nFlg = spinlock_disable( &g_sSPinLock );
	if ( psPort->sp_nBaudRate > 0 ) {
	    uint nDivisor = 115200 / psPort->sp_nBaudRate;
	    ser_out( psPort, UART_LCR, 0x83 ); // Set bit 7 to enable baud rate divisors
	    ser_out( psPort, UART_DLL, nDivisor & 0xff ); // Baud rate divisor LSB
	    ser_out( psPort, UART_DLM, nDivisor >> 8  ); // Baud rate divisor MSB
	    ser_out( psPort, UART_LCR, 0x03 ); // Clr bit 7 to disable baud rate divisors
	}
Пример #12
0
/**
 * Copy a NULL-terminated array of strings from user memory.
 *
 * Copies a NULL-terminated array of strings from user memory. The array
 * itself and each array entry must be freed with kfree() once no longer
 * needed.
 *
 * @param src		Array to copy.
 * @param arrayp	Pointer to location in which to store address of
 *			allocated array.
 *
 * @return		Status code describing result of the operation.
 */
status_t arrcpy_from_user(const char *const src[], char ***arrayp) {
	char **array = NULL, **narr;
	status_t ret;
	int i;

	/* Copy the arrays across. */
	for(i = 0; ; i++) {
		narr = krealloc(array, sizeof(char *) * (i + 1), MM_USER);
		if(!narr) {
			ret = STATUS_NO_MEMORY;
			goto fail;
		}

		array = narr;
		array[i] = NULL;

		ret = memcpy_from_user(&array[i], &src[i], sizeof(char *));
		if(ret != STATUS_SUCCESS) {
			array[i] = NULL;
			goto fail;
		} else if(array[i] == NULL) {
			break;
		}

		ret = strdup_from_user(array[i], &array[i]);
		if(ret != STATUS_SUCCESS) {
			array[i] = NULL;
			goto fail;
		}
	}

	*arrayp = array;
	return STATUS_SUCCESS;
fail:
	if(array) {
		for(i = 0; array[i] != NULL; i++)
			kfree(array[i]);

		kfree(array);
	}

	return ret;
}
Пример #13
0
/**
 * Duplicate a string from user memory.
 *
 * Allocates a buffer large enough and copies across a string from user memory.
 * If the string is longer than the maximum length, then an error will be
 * returned. Because a length limit is provided, the allocation is made using
 * MM_WAIT - it is assumed that the limit is sensible.
 *
 * @param src		Location to copy from.
 * @param max		Maximum length allowed.
 * @param destp		Pointer to location in which to store address of
 *			destination buffer.
 *
 * @return		Status code describing result of the operation.
 *			Returns STATUS_INVALID_ARG if the string is
 *			zero-length.
 */
status_t strndup_from_user(const void *src, size_t max, char **destp) {
	status_t ret;
	size_t len;
	char *d;

	ret = strlen_user(src, &len);
	if(ret != STATUS_SUCCESS) {
		return ret;
	} else if(len == 0) {
		return STATUS_INVALID_ARG;
	} else if(len > max) {
		return STATUS_TOO_LONG;
	}

	d = kmalloc(len + 1, MM_KERNEL);
	ret = memcpy_from_user(d, src, len);
	if(ret != STATUS_SUCCESS) {
		kfree(d);
		return ret;
	}
	d[len] = 0;
	*destp = d;
	return STATUS_SUCCESS;
}