?? write.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 + -