⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtd-dm6430.c

📁 rt 6430 采集卡 linux下驱动源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	printk(	    KERN_INFO "MOUTW io + 0x%04x = 0x%04x(0x%04x/0x%04x)\n",	    io_rq.reg,	    *value_p,	    io_rq.value,	    io_rq.mask	);#endif    return 0;}static intDM6430HR_IOCTL_CLEAR_Handler(struct Dm6430hrDevice *device_p, ulong arg) {    spin_lock(&device_p->lock);    DM6430HRClear(device_p, arg);    spin_unlock(&device_p->lock);    return 0;}	static intDM6430HR_IOCTL_IRQ_INSTALL_Handler(struct Dm6430hrDevice *device_p, ulong arg) {    int				status;    struct DM6430HR_CallBack	cb;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_INSTALL_ISR()\n");#endif    if (copy_from_user(&cb, (struct DM6430HR_CallBack *) arg, sizeof(cb)))	return -EFAULT;    status = validate_interrupt_circuit(cb.intr);    if (status != 0) {	return status;    }    if (!device_p->irq[cb.intr] || (cb.signo >= _NSIG))	return -EINVAL;    spin_lock(&device_p->lock);    if (cb.action) {	device_p->callback[cb.intr].signo = cb.signo;	device_p->callback[cb.intr].process = current;	device_p->callback[cb.intr].context = cb.context;    } else {	cb.context = device_p->callback[cb.intr].context;	device_p->callback[cb.intr].signo = 0;	device_p->callback[cb.intr].process = 0;	device_p->callback[cb.intr].context = 0;    }    spin_unlock(&device_p->lock);    if (!cb.action)	if (copy_to_user((struct DM6430HR_CallBack *) arg, &cb, sizeof(cb)))	    return -EFAULT;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_INSTALL_ISR() end\n");#endif	    return 0;}static intDM6430HR_IOCTL_IRQ_ENABLE_Handler(struct Dm6430hrDevice *device_p, ulong arg) {    int			status;    struct DM6430HR_IE	io_rq;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_IRQ_ENABLE()\n");#endif    if (copy_from_user(&io_rq, (struct DM6430HR_IE *) arg, sizeof(io_rq)))	return -EFAULT;    status = validate_interrupt_circuit(io_rq.intr);    if (status != 0) {	return status;    }    if (!device_p->irq[io_rq.intr])	return -EINVAL;        spin_lock(&device_p->lock);    DM6430HRIRQEnable(device_p, io_rq.intr, io_rq.action ? 1 : 0 );    spin_unlock(&device_p->lock);#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_IRQ_ENABLE() end\n");#endif    return 0;}static intDM6430HR_IOCTL_DMA_INSTALL_Handler(struct Dm6430hrDevice *device_p, ulong arg) {    int			status;    struct dm_dma_buf	*buf_p;    struct DM6430HR_DI	io_rq;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_DMA_INSTALL()\n");#endif    if (copy_from_user(&io_rq, (struct DM6430HR_DI *) arg, sizeof(io_rq)))	return -EFAULT;    status = validate_dma_circuit(io_rq.dma);    if (status != 0) {	return status;    }    if (!device_p->dma[io_rq.dma])	return -EINVAL;    buf_p = &device_p->dmabuf[io_rq.dma];	    if (io_rq.action) {	if (buf_p->addr)	    return 0;	spin_lock(&device_p->lock);	buf_p->addr = (char *) dm_dma_mem_alloc(buflength);	buf_p->length = buflength;	spin_unlock(&device_p->lock);    	if (!buf_p->addr)	    return -ENOMEM;	memset(buf_p->addr, 0, buflength);    } else {//    m_Dma[Channel].TerminateXfer();	dm_stop_dma(device_p, io_rq.dma);    	spin_lock(&device_p->lock);	if (buf_p->addr)	    dm_dma_mem_free((unsigned long) buf_p->addr, buf_p->length);	buf_p->length = 0;	buf_p->addr = 0;	spin_unlock(&device_p->lock);    }    return 0;}static intDM6430HR_IOCTL_DMA_GETDATA_Handler(struct Dm6430hrDevice *device_p, ulong arg) {    int			status;    struct DM6430HR_GDD	io_rq;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_DMA_GETDATA()\n");#endif    if (copy_from_user(&io_rq, (struct DM6430HR_GDD *) arg, sizeof(io_rq)))	return -EFAULT;    status = validate_dma_circuit(io_rq.dma);    if (status != 0) {	return status;    }    if (	!device_p->dma[io_rq.dma]	||	!device_p->dmabuf[io_rq.dma].addr	||	((io_rq.offset + io_rq.length) > device_p->dmabuf[io_rq.dma].length)    )	return -EINVAL;    if (	copy_to_user(	    io_rq.buf,	    (device_p->dmabuf[io_rq.dma].addr + io_rq.offset),	    io_rq.length	)    )	return -EFAULT;    return 0;}static intDM6430HR_IOCTL_DMA_GETINC_Handler(struct Dm6430hrDevice *device_p, ulong arg) {    struct DM6430HR_GID	io_rq;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_DMA_GETINC()\n");#endif    if (copy_from_user(&io_rq, (struct DM6430HR_GID *) arg, sizeof(io_rq)))	return -EFAULT;    switch (io_rq.port) {	case rSTR_AD_6430:	case rSTR_DIN_FIFO_6430:	    break;	default:	    return -EINVAL;	    break;    }    switch (io_rq.type) {	case DM6430HR_STR_TYPE_BYTE:	case DM6430HR_STR_TYPE_WORD:	    break;	default:	    return -EINVAL;	    break;    }    /*     * Do not allow byte transfers from A/D FIFO     */    if (	(io_rq.port == rSTR_AD_6430)	&&	(io_rq.type != DM6430HR_STR_TYPE_WORD)    ) {	return -EOPNOTSUPP;    }    /*     * Do not allow word transfers from digital input FIFO     */    if (	(io_rq.port == rSTR_DIN_FIFO_6430)	&&	(io_rq.type != DM6430HR_STR_TYPE_BYTE)    ) {	return -EOPNOTSUPP;    }    /*     * Each FIFO has 1024 elements, don't allow more in one read     */    if (io_rq.times > 1024) {	return -EINVAL;    }    if (io_rq.times) {	io_rq.port += device_p->io;	spin_lock(&device_p->lock);	/*	 * Do I/O into kernel stream read buffer, not into user space buffer.	 * In order to do I/O into a user space buffer, it must be remapped	 * into kernel space using the kiobuf interface.  It's a stupid idea	 * to do I/O directly into a user buffer without remapping because	 * 1) the kernel is not set up do so, 2) it is a user address, 3) the	 * 3) address can refer to anything or anywhere, 4) the address may	 * not even be valid or in memory, 5) access_ok()/verify_area() can	 * "approve" a user address which can later cause a fault, and 6) the	 * I/O occurs into a kernel area that probably should not be mucked	 * with.  Just say no to I/O directly into user space.	 */	switch (io_rq.type) {	    case DM6430HR_STR_TYPE_BYTE:		dm_insb(io_rq.port, device_p->stream_buff_p, io_rq.times);		break;	    case DM6430HR_STR_TYPE_WORD:		dm_insw(io_rq.port, device_p->stream_buff_p, io_rq.times);		break;	}	spin_unlock(&device_p->lock);	if (	    copy_to_user(		io_rq.buf,		device_p->stream_buff_p,		(io_rq.times * io_rq.type)	    )	) {	    return -EFAULT;	}    }    return 0;}unsigned long flags;static intDM6430HR_IOCTL_DMA_START_Handler(struct Dm6430hrDevice *device_p, ulong arg) {    int			channel;    int			status;    struct dm_dma_buf	*buf_p;    struct DM6430HR_DST	io_rq;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_DMA_START()\n");#endif    if (copy_from_user(&io_rq, (struct DM6430HR_DST *) arg, sizeof(io_rq)))	return -EFAULT;    status = validate_dma_circuit(io_rq.dma);    if (status != 0) {	return status;    }    if (	!device_p->dma[io_rq.dma]	||	!device_p->dmabuf[io_rq.dma].addr	||	(io_rq.length & 1)	||	(io_rq.length > device_p->dmabuf[io_rq.dma].length)    )	return -EINVAL;    channel = device_p->dma[io_rq.dma];    buf_p = &device_p->dmabuf[io_rq.dma];	    //m_Dma[Channel].Initiate(&I, this, Offset, xFerLength, bDemand);    flags = claim_dma_lock();    //fixme FIRST DMA FLAG bug test only     //memset(bufp->addr, 0, bufp->length);    disable_dma(channel);    clear_dma_ff(channel);    set_dma_mode(channel, DMA_MODE_READ);    set_dma_addr(channel, virt_to_bus(buf_p->addr));    set_dma_count(channel, io_rq.length);    enable_dma(channel);    //release_dma_lock(flags);    return 0;}static intDM6430HR_IOCTL_DMA_STOP_Handler(struct Dm6430hrDevice *device_p, ulong arg) {    int	status;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_DMA_STOP(%ld)\n", arg);#endif    status = validate_dma_circuit(arg);    if (status != 0) {	return status;    }    if (!device_p->dma[arg])	return -EINVAL;    //return m_Dma[Channel].TerminateXfer();    //flags = claim_dma_lock();    disable_dma(device_p->dma[arg]);    clear_dma_ff(device_p->dma[arg]);    release_dma_lock(flags);    return 0;}static intDM6430HR_IOCTL_GET_IRQ_COUNTER_Handler(    struct Dm6430hrDevice *device_p,    ulong arg) {    int			status;    struct DM6430HR_GIC	io_rq;#ifdef DEBUG    if (debug & DBG_IOCTLS)	printk(KERN_INFO "DM6430HR_GET_IRQ_COUNTER()\n");#endif    if (copy_from_user(&io_rq, (struct DM6430HR_GIC *) arg, sizeof(io_rq)))	return -EFAULT;    status = validate_interrupt_circuit(io_rq.intr);    if (status != 0) {	return status;    }    if (!device_p->irq[io_rq.intr])	return -EINVAL;    spin_lock(&device_p->lock);    io_rq.counter = device_p->irq_count[io_rq.intr];    spin_unlock(&device_p->lock);    if (copy_to_user((struct DM6430HR_GIC *) arg, &io_rq, sizeof(io_rq)))	return -EFAULT;    return 0;}static intdm6430hr_ioctl(    struct inode *inode_p,    struct file *file_p,    uint cmd,    ulong arg) {    int				rc = 0;    struct Dm6430hrDevice	*device_p;#ifdef DEBUG    if (debug & DBG_FILEOPS)	printk(KERN_INFO "dm6430hr_ioctl()\n");#endif       device_p = (struct Dm6430hrDevice *) file_p->private_data;    if (!device_p)	return -EINVAL;    switch (cmd) {	case DM6430HR_IOCTL_OUTW:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_OUTW_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_MOUTW:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_MOUTW_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_OUTB:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_OUTB_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_MOUTB:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_MOUTB_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_INW:	    if (!(file_p->f_mode & FMODE_READ))		return -EACCES;	    rc = DM6430HR_IOCTL_INW_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_INB:	    if (!(file_p->f_mode & FMODE_READ))		return -EACCES;	    rc = DM6430HR_IOCTL_INB_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_CLEAR:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_CLEAR_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_IRQ_INSTALL:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_IRQ_INSTALL_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_IRQ_ENABLE:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_IRQ_ENABLE_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_DMA_INSTALL:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_DMA_INSTALL_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_DMA_START:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_DMA_START_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_DMA_STOP:	    if (!(file_p->f_mode & FMODE_WRITE))		return -EACCES;	    rc = DM6430HR_IOCTL_DMA_STOP_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_DMA_GETDATA:	    if (!(file_p->f_mode & FMODE_READ))		return -EACCES;	    rc = DM6430HR_IOCTL_DMA_GETDATA_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_DMA_GETINC:	    if (!(file_p->f_mode & FMODE_READ))		return -EACCES;	    rc = DM6430HR_IOCTL_DMA_GETINC_Handler(device_p, arg);	    break;	case DM6430HR_IOCTL_GET_IRQ_COUNTER:	    if (!(file_p->f_mode & FMODE_READ))		return -EACCES;	    rc = DM6430HR_IOCTL_GET_IRQ_COUNTER_Handler(device_p, arg);	    break;	default:	    rc = -EINVAL;    }    return rc;}static struct file_operations driver_fops = {	owner:   THIS_MODULE,	open:	dm6430hr_open,	ioctl:	dm6430hr_ioctl,		release: dm6430hr_release,};static voiddm6430hr_interrupt(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -