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

📄 write.c

📁 can bus driver code.
💻 C
字号:
/* write.c * Linux CAN-bus device driver. * Written by Arnaud Westenberg email:arnaud@wanadoo.nl * This software is released under the GPL-License. * Version 0.7  6 Aug 2001 */#include <linux/autoconf.h>#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)#define MODVERSIONS#endif#if defined (MODVERSIONS)#include <linux/modversions.h>#endif#define __NO_VERSION__#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/delay.h>#include <asm/irq.h>#include <asm/uaccess.h>#include "../include/main.h"ssize_t can_write(struct file *file, const char *buffer, size_t length, loff_t *offset){	struct msgobj_t *obj;	struct chip_t *chip;	struct canmsg_t *write_msg;	struct canfifo_t *fifo;	int ret = 0;	int space = 0;	int written = 0;	int bytes_to_copy = 0;	long can_timeout = 1;	if (length < sizeof(struct canmsg_t)) {		DEBUGMSG("Trying to write less bytes than a CAN message,\n");		DEBUGMSG("this will always return 0 !\n");		return 0;	}	if (length > 8 * sizeof(struct canmsg_t)) {		CANMSG("Trying to write more than is supported.\n");		return -1;	}	if (length % sizeof(struct canmsg_t)) {		CANMSG("The number of bytes requested to be written is not a multiple of\n");		CANMSG("'sizeof(struct canmsg_t)', currently this is not allowed.\n");		return -1;	} 	/* Initialize hardware pointers */	if ( (obj = objects_p[MINOR_NR]) == NULL) {		CANMSG("Could not assign buffer structure\n");		return -1;	}	if ( (chip = obj->hostchip) == NULL) {		CANMSG("Device is not correctly configured,\n");		CANMSG("please reload the driver\n");		return -1;	}	if ( (fifo = obj->fifo) == NULL) {		CANMSG("Could not assign buffer memory\n");		return -1;	}	/* Initialize pointer to the first message to be sent */	write_msg = fifo->tx_writep;	/* Calculate free buffer space */	cli();	space = ((int)fifo->tx_writep < (int)fifo->tx_readp) ? 			((int)fifo->tx_readp - (int)fifo->tx_writep) : 			((int)fifo->tx_readp - (int)fifo->tx_writep + 							(int)fifo->tx_size);	sti();	/* If the output buffer is full, return immediately in case O_NONBLOCK	 * has been specified or loop until space becomes available.	 */	while (space < sizeof(struct canmsg_t)) {		DEBUGMSG("Buffer is full\n");		if (file->f_flags & O_NONBLOCK)			return -EAGAIN;		can_timeout = interruptible_sleep_on_timeout(&fifo->writeq, 								CANTIMEOUT);		if (signal_pending(current))			return -EINTR;		if (!can_timeout)			return -EIO;		cli();		space = ((int)fifo->tx_writep < (int)fifo->tx_readp) ? 			((int)fifo->tx_readp - (int)fifo->tx_writep) : 			((int)fifo->tx_readp - (int)fifo->tx_writep + 							(int)fifo->tx_size);		sti();	}	/* There's space available in the kernel output buffer.	 * Find out wich is smaller: 'length', the number of bytes requested to	 * be written or 'space', the number of bytes available in the kernel 	 * buffer. We copy the least of the two to kernel space.	 *///	space = space - (space % sizeof(struct canmsg_t)); // round it	bytes_to_copy = space < length ? space : length;	copy_from_user(fifo->tx_writep, buffer, bytes_to_copy);	written = bytes_to_copy;	while (bytes_to_copy > 0) {		fifo->tx_writep++;		if (fifo->tx_writep >= fifo->buf_tx_entry + MAX_BUF_LENGTH)			fifo->tx_writep = fifo->buf_tx_entry;		bytes_to_copy -= sizeof(struct canmsg_t);	}	/* Copy the data to be transmitted into the output buffer *//*	while ( (written < length) && (space >= sizeof(struct canmsg_t)) ) {		copy_from_user(fifo->tx_writep,buffer, sizeof(struct canmsg_t));		cli();		fifo->tx_writep++;		if (fifo->tx_writep >= fifo->buf_tx_entry + MAX_BUF_LENGTH)			fifo->tx_writep = fifo->buf_tx_entry;		buffer += sizeof(struct canmsg_t);		written += sizeof(struct canmsg_t);		space = ((int)fifo->tx_writep < (int)fifo->tx_readp) ?			((int)fifo->tx_readp - (int)fifo->tx_writep) :			((int)fifo->tx_readp - (int)fifo->tx_writep + 							(int)fifo->tx_size);		sti();	} */	/* Initiate transmission in case we are not already transmitting */	cli();	if (!fifo->tx_in_progress) {		fifo->tx_in_progress = 1;		sti();		if ( (ret = chip->chipspecops->pre_write_config(chip, obj, 							write_msg)) < 0) {			CANMSG("Error initializing hardware for sending\n");			return -EIO;		}		obj->ret = 0;		if ( (ret = chip->chipspecops->send_msg(chip, obj, 							write_msg)) < 0) {			CANMSG("Error sending message\n");			return -EIO;		}		/* If O_SYNC is specified wait for successfull transmission *//*		while (1) {			cli();			if ( (!file->f_flags & O_SYNC) || 						(!fifo->tx_in_progress)) {				sti();				if (obj->ret < 0)					return obj->ret;				else					return written;			}			cli();			if (fifo->tx_in_progress) {				can_timeout = interruptible_sleep_on_timeout(						&fifo->writeq, CANTIMEOUT);			}			sti();			if (signal_pending(current))				return -EINTR;			if (!can_timeout)				return -EIO;		} */	}	sti();	return written;}	

⌨️ 快捷键说明

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