コード例 #1
0
ファイル: main_dma.c プロジェクト: QuickJack/logi-kernel
static inline ssize_t writeMem(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
	unsigned short int transfer_size;
	ssize_t transferred = 0;
	unsigned long src_addr, trgt_addr;
	struct drvr_mem * mem_to_write = &(((struct drvr_device *) filp->private_data)->data);

#ifdef USE_WORD_ADDRESSING
	if (count % 2 != 0) {
		DBG_LOG("write: Transfer must be 16bits aligned\n");

		return -EFAULT;
	}
#endif

	if (count < MAX_DMA_TRANSFER_IN_BYTES) {
		transfer_size = count;
	} else {
		transfer_size = MAX_DMA_TRANSFER_IN_BYTES;
	}

#ifdef USE_WORD_ADDRESSING
	trgt_addr = (unsigned long) &(mem_to_write->base_addr[(*f_pos) / 2]);
#else
	trgt_addr = (unsigned long) &(mem_to_write->base_addr[(*f_pos)]);
#endif

	src_addr = (unsigned long) dmaphysbuf;

	if (copy_from_user(mem_to_write->dma.buf, buf, transfer_size)) {
		return -EFAULT;
	}

	if(transfer_size <= 256){		
		memcpy((void *) &(mem_to_write->virt_addr[(*f_pos)]), mem_to_write->dma.buf,transfer_size);

		return transfer_size ;
	}

	while (transferred < count) {
		int res;

#ifdef PROFILE
		DBG_LOG("Write\n");
		start_profile();
#endif

		res = logi_dma_copy(mem_to_write, trgt_addr, src_addr,
				    transfer_size);
		if (res < 0) {
			DBG_LOG("write: Failed to trigger EDMA transfer\n");

			return res;
		}

#ifdef PROFILE
		stop_profile();
		compute_bandwidth(transfer_size);
#endif

		trgt_addr += transfer_size;
		transferred += transfer_size;

		if ((count - transferred) < MAX_DMA_TRANSFER_IN_BYTES) {
			transfer_size = count - transferred;
		} else {
			transfer_size = MAX_DMA_TRANSFER_IN_BYTES;
		}

		if (copy_from_user(mem_to_write->dma.buf, &buf[transferred], transfer_size)) {
			return -EFAULT;
		}
	}

	return transferred;
}
コード例 #2
0
ファイル: main_dma.c プロジェクト: genba/Logi-kernel
ssize_t writeMem(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
	unsigned short int transfer_size;
	ssize_t transferred = 0;
	unsigned long src_addr, trgt_addr;
	struct drvr_mem * mem_to_write = &(((struct drvr_device *) filp->private_data)->data.mem);

	if (count % 2 != 0) {
		printk("%s: write: Transfer must be 16bits aligned.\n", DEVICE_NAME);

		return -1;
	}

	if (count < MAX_DMA_TRANSFER_IN_BYTES) {
		transfer_size = count;
	} else {
		transfer_size = MAX_DMA_TRANSFER_IN_BYTES;
	}

	if (mem_to_write->dma_buf == NULL) {
		printk("failed to allocate DMA buffer \n");

		return -1;
	}

	trgt_addr = (unsigned long) &(mem_to_write->base_addr[(*f_pos) / 2]);
	src_addr = (unsigned long) dmaphysbuf;

	if (copy_from_user(mem_to_write->dma_buf, buf, transfer_size)) {
		return -1;
	}

	while (transferred < count) {

#ifdef PROFILE
		printk("Write \n");
		start_profile();
#endif

		if (edma_memtomemcpy(transfer_size, src_addr, trgt_addr, mem_to_write->dma_chan) < 0) {
			printk("%s: write: Failed to trigger EDMA transfer.\n", DEVICE_NAME);

			return -1;
		}

#ifdef PROFILE
		stop_profile();
		compute_bandwidth(transfer_size);
#endif

		trgt_addr += transfer_size;
		transferred += transfer_size;

		if ((count - transferred) < MAX_DMA_TRANSFER_IN_BYTES) {
			transfer_size = count - transferred;
		} else {
			transfer_size = MAX_DMA_TRANSFER_IN_BYTES;
		}

		if (copy_from_user(mem_to_write->dma_buf, &buf[transferred], transfer_size)) {
			return -1;
		}
	}

	return transferred;
}