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

📄 rtl_posixio.c

📁 fsmlabs的real time linux的内核
💻 C
字号:
/* * (C) Finite State Machine Labs Inc. 1999-2001 <business@fsmlabs.com> * * Released under the terms of GPL 2. * Open RTLinux makes use of a patented process described in * US Patent 5,995,745. Use of this process is governed * by the Open RTLinux Patent License which can be obtained from * www.fsmlabs.com/PATENT or by sending email to * licensequestions@fsmlabs.com *  *//* *  Originally derived from the Linux VFS code *  Copyright (C) 1991-1993  Linus Torvalds *//* CangeLog * Feb 11 2003 Mattias Sjoesvaerd <mattias@syrensoftware.se>  *      fix for resource releas if open via f_op fails. */#include <linux/module.h>#include <linux/kernel.h>#include <linux/version.h>#include <linux/config.h>#include <linux/fs.h>#include <linux/major.h>#include <linux/string.h>#include <linux/sched.h>#include <linux/stat.h>#include <linux/fcntl.h>#include <linux/errno.h>#include <linux/ctype.h>#include <asm/io.h>#include <rtl_posixio.h>#include <sys/mman.h>#include <errno.h>#include <unistd.h>#include <rtl.h>#include <rtl_core.h>MODULE_LICENSE("GPL v2");MODULE_AUTHOR("FSMLabs Inc.");MODULE_DESCRIPTION("POSIX API support for RTLinux");#define MAX_RTL_FILES 128static struct rtl_file rtl_files [MAX_RTL_FILES] /* TODO __attribute__ ((aligned (64))) */ = {	{ NULL, 0 },};struct device_struct {	const char * name;	struct rtl_file_operations * fops;};static struct device_struct rtldevs[MAX_CHRDEV] = {	{ NULL, NULL },};int rtl_register_rtldev(unsigned int major, const char * name, struct rtl_file_operations *fops){	if (major >= MAX_CHRDEV)		return -EINVAL;	if (rtldevs[major].fops && rtldevs[major].fops != fops) {		return -EBUSY;	}	rtldevs[major].name = name;	rtldevs[major].fops = fops;	return 0;}int rtl_unregister_rtldev(unsigned int major, const char * name){	if (major >= MAX_CHRDEV)		return -EINVAL;	if (!rtldevs[major].fops)		return -EINVAL;	if (strcmp(rtldevs[major].name, name))		return -EINVAL;	rtldevs[major].name = NULL;	rtldevs[major].fops = NULL;	return 0;}/* we assume all RTLinux file names are of the form /dev/devicename<number> */int open(const char *pathname, int flags){	int i;	int minor;	int major;	char devname[200];	char *p;	int ret;	if (strncmp(pathname, "/dev/", 5)) {		__set_errno(ENOENT);		return -1; /* here we can use some other name resolution scheme */	}	i = 0;	while (i < sizeof(devname) - 1 && *(pathname + 5 + i) && !isdigit(*(pathname + 5 + i))) {		devname[i] = *(pathname + 5 + i);		i++;	}	devname[i] = 0;	if (isdigit(*(pathname + 5 + i))) {		minor = simple_strtoul (pathname + 5 + i, &p, 10);	} else if (!*(pathname + 5 + i)) {		minor = 0; /* like /dev/mem */	} else {		__set_errno(ENOENT);		return -1;	}		for (i = 0; i < MAX_CHRDEV; i ++) {		if (rtldevs[i].name && !strcmp(rtldevs[i].name, devname)) {			goto found_major;		}	} 	rtl_printf("rtl_posixio: dev entry %s not found\n", pathname); 	__set_errno(ENOENT);	return -1;found_major:	major = i;	for (i = 0; i < MAX_RTL_FILES; i ++) {		if (!rtl_files[i].f_op) {			goto found_free;		}	}	__set_errno(ENOMEM);	return -1;found_free:	rtl_files[i].f_op = rtldevs[major].fops;	rtl_files[i].f_minor = minor;	rtl_files[i].f_flags = flags;	ret = rtl_files[i].f_op->open(&rtl_files[i]);	if (ret < 0) {                /* if open fails free the resources - Mattias 		 * Sjoesvaerd <mattias@syrensoftware.se> 		 */		rtl_files[i].f_op = NULL;  		rtl_files[i].f_minor = 0;  		rtl_files[i].f_flags = 0; 		__set_errno(-ret);		return -1;	}	return i;}#define CHECKFD(fd) \	if ((unsigned int) (fd) >= MAX_RTL_FILES || !rtl_files[fd].f_op) { \		__set_errno(EBADF); \		return -1; \	}extern int rtl_get_minor(int fd){	CHECKFD(fd);	return RTL_MINOR_FROM_FILEPTR(&rtl_files[fd]);}int close(int fd){	CHECKFD(fd);	rtl_files[fd].f_op->release(&rtl_files[fd]);	rtl_files[fd].f_op = NULL;	return 0;}ssize_t write(int fd, const void *buf, size_t count){	int ret;	CHECKFD(fd);	ret = rtl_files[fd] . f_op -> write (&rtl_files[fd], buf, count, &rtl_files[fd].f_pos);	if (ret < 0) {		__set_errno(-ret);		return -1;	}	return ret;}ssize_t read(int fd, void *buf, size_t count){	int ret;	CHECKFD(fd);	ret = rtl_files[fd] . f_op -> read (&rtl_files[fd], buf, count, &rtl_files[fd].f_pos);	if (ret < 0) {		__set_errno(-ret);		return -1;	}	return ret;}/* TODO lseek */caddr_t  mmap(void  *start,  size_t length, int prot , int flags, int fd, off_t offset){	int ret;	caddr_t result;	if ((unsigned int) (fd) >= MAX_RTL_FILES || !rtl_files[fd].f_op) {		__set_errno(EBADF);		return (caddr_t) -1;	}	if (! rtl_files[fd] . f_op -> mmap) {		__set_errno(EINVAL);		return (caddr_t) -1;	}	ret = rtl_files[fd] . f_op -> mmap (&rtl_files[fd], start, length, prot, flags, offset, &result);	if (ret != 0) {		__set_errno(-ret);		return (caddr_t) -1;	}	return result;}int munmap(void *start, size_t length){	iounmap (start);	return 0;}int ioctl(int fd, int request, ...){	int ret;	va_list list;	unsigned long arg;	va_start (list, request);	arg = va_arg(list, unsigned long);	va_end (list);		CHECKFD(fd);	ret = rtl_files[fd] . f_op -> ioctl (&rtl_files[fd], request, arg);	if (ret < 0) {		__set_errno(-ret);		return -1;	}	return 0;}#ifndef CONFIG_RTL_DEVMEM_SUPPORTint init_module(void) {return 0;}void cleanup_module(void){return; }#else #include <asm/io.h>static int rtl_mem_open (struct rtl_file *filp){	return 0;}static int rtl_mem_release (struct rtl_file *filp){	filp->f_pos = 0;	return 0;}static ssize_t rtl_mem_write(struct rtl_file *filp, const char *buf, size_t count, loff_t* ppos){	memcpy_toio ((long) *ppos, buf, count);	*ppos += count;	return count;}static ssize_t rtl_mem_read(struct rtl_file *filp, char *buf, size_t count, loff_t* ppos){	memcpy_fromio (buf, (long) *ppos, count);	*ppos += count;	return count;}static int rtl_mem_mmap (struct rtl_file *file, void  *start,  size_t length, int prot , int flags, off_t offset, caddr_t *result){	/* TODO need to fail if MAP_FIXED was specified etc */	if (!rtl_rt_system_is_idle()) {		return -EAGAIN;	}	*result = ioremap (offset, length);	if (!*result) {		return -EINVAL;	}	return 0;}static loff_t rtl_mem_llseek(struct rtl_file *file, loff_t offset, int origin){	if (origin != SEEK_SET) {		return -EINVAL;	}	return file->f_pos = offset;}static struct rtl_file_operations rtl_mem_fops = {       	rtl_mem_llseek,	rtl_mem_read,	rtl_mem_write,	NULL,	rtl_mem_mmap,	rtl_mem_open,	rtl_mem_release};int init_module(void){	if (rtl_register_rtldev (MEM_MAJOR, "mem", &rtl_mem_fops)) {		printk ("RTLinux /dev/mem: unable to get RTLinux major %d\n", MEM_MAJOR);		return -EIO;	}	return 0;}void cleanup_module(void){	rtl_unregister_rtldev(MEM_MAJOR, "mem");}#endif

⌨️ 快捷键说明

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