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

📄 upci.c

📁 CNC 的开放码,EMC2 V2.2.8版
💻 C
📖 第 1 页 / 共 2 页
字号:
{    if ( ioaccess <= 0 ) {	/* should not be calling decr if already zero */	return;    }    /* decrement reference count */    ioaccess--;    if ( ioaccess == 0 ) {	/* release I/O priveleges */	iopl(0);    }}static int incr_mem_usage ( void ){    int eno;    /* make sure /dev/mem is open */    if ( memaccess == 0 ) {	/* open it */	/* this needs priviliges */	if (seteuid(0) != 0) {	    errmsg(__func__, "need root privilges (or setuid root)");	    return -1;	}	/* do it */	memfd = open("/dev/mem", O_RDWR);	eno = errno;	/* drop priviliges */	seteuid(getuid());	/* check result */	if ( memfd < 0 ) {	    errmsg(__func__,"can't open /dev/mem: %s", strerror(eno));	    return -1;	}    }    /* increment reference count */    memaccess++;    return 0;}static void decr_mem_usage ( void ){    if ( memaccess <= 0 ) {	/* should not be calling decr if already zero */	return;    }    /* decrement reference count */    memaccess--;    if ( memaccess == 0 ) {	/* close /dev/mem */	close(memfd);    }}int upci_open_region(int devnum, int region_num){    struct dev_info *dev;    struct region_info *reg;    int rd;    if (( devnum < 0 ) || ( devnum >= num_devs )) {	errmsg(__func__, "device %d not found", devnum);	return -1;    }    dev = devices[devnum];    if (( region_num < 0 ) || ( region_num >= 6 )) {	errmsg(__func__, "bad region number %d", region_num);	return -1;    }    reg = &(dev->regions[region_num]);    if ( reg->size == 0 ) {	errmsg(__func__, "region %d not found in device %d",	    region_num, devnum);	return -1;    }    /* calculate region descriptor */    rd = devnum * 6 + region_num;    if ( reg->region_is_mapped ) {	/* already open, nothing to do */	return rd;    }    if ( reg->type == UPCI_REG_IO ) {	/* region is IO, no mapping needed */	/* update reference counter */	if ( incr_io_usage() != 0 ) {	    errmsg(__func__, "no I/O access");	    return -1;	}    } else {	/* region is memory */	/* update reference counter */	if ( incr_mem_usage() != 0 ) {	    return -1;	}	/* map the memory region */	reg->mapped_ptr = mmap(0, reg->size, PROT_READ | PROT_WRITE,	    MAP_SHARED, memfd, reg->base_addr);	if ( reg->mapped_ptr == MAP_FAILED ) {	    reg->mapped_ptr = NULL;	    errmsg(__func__, "can't map /dev/mem for device %d, region %d: %s",		devnum, region_num, strerror(errno));	    decr_mem_usage();	    return -1;	}    }    /* mark region as mapped */    reg->region_is_mapped = 1;    regions[rd] = reg;    return rd;}void upci_close_region(int rd){    struct region_info *reg;    if ((rd < 0 ) || ( rd >= MAX_REGIONS )) return;    reg = regions[rd];    if ( reg == NULL ) return;    if ( reg->type == UPCI_REG_IO ) {	/* region is IO, nothing to unmap */	decr_io_usage();    } else {	/* region is memory, unmap it */	munmap ( reg->mapped_ptr, reg->size );	decr_mem_usage();    }    /* mark region as unmapped */    reg->region_is_mapped = 0;    regions[rd] = NULL;}__u8 upci_read_u8(int rd, __u32 offset){    struct region_info *reg;    int port;    volatile __u8 *ptr, data;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) || 	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return 0;    /* get the data */    if ( reg->type == UPCI_REG_IO ) {	/* region is IO */	port = reg->base_addr + offset;	data = inb(port);    } else {	/* region is memory */	ptr = (__u8 *)(reg->mapped_ptr + offset);	data = *ptr;    }    return data;}__s8 upci_read_s8(int rd, __u32 offset){    struct region_info *reg;    int port;    volatile __s8 *ptr, data;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return 0;    /* get the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	data = inb(port);    } else {	ptr = (__s8 *)(reg->mapped_ptr + offset);	data = *ptr;    }    return data;}__u16 upci_read_u16(int rd, __u32 offset){    struct region_info *reg;    int port;    volatile __u16 *ptr, data;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return 0;    /* get the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	data = inw(port);    } else {	ptr = (__u16 *)(reg->mapped_ptr + offset);	data = *ptr;    }    return data;}__s16 upci_read_s16(int rd, __u32 offset){    struct region_info *reg;    int port;    volatile __s16 *ptr, data;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return 0;    /* get the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	data = inw(port);    } else {	ptr = (__s16 *)(reg->mapped_ptr + offset);	data = *ptr;    }    return data;}__u32 upci_read_u32(int rd, __u32 offset){    struct region_info *reg;    int port;    volatile __u32 *ptr, data;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return 0;    /* get the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	data = inl(port);    } else {	ptr = (__u32 *)(reg->mapped_ptr + offset);	data = *ptr;    }    return data;}__s32 upci_read_s32(int rd, __u32 offset){    struct region_info *reg;    int port;    volatile __s32 *ptr, data;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return 0;    /* get the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	data = inl(port);    } else {	ptr = (__s32 *)(reg->mapped_ptr + offset);	data = *ptr;    }    return data;}void upci_write_u8(int rd, __u32 offset, __u8 data){    struct region_info *reg;    int port;    volatile __u8 *ptr;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) || 	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return;    /* write the data */    if ( reg->type == UPCI_REG_IO ) {	/* region is IO */	port = reg->base_addr + offset;	outb(data, port);    } else {	/* region is memory */	ptr = (__u8 *)(reg->mapped_ptr + offset);	*ptr = data;    }    return;}void upci_write_s8(int rd, __u32 offset, __s8 data){    struct region_info *reg;    int port;    volatile __s8 *ptr;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return;    /* write the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	outb(data, port);    } else {	ptr = (__s8 *)(reg->mapped_ptr + offset);	*ptr = data;    }    return;}void upci_write_u16(int rd, __u32 offset, __u16 data){    struct region_info *reg;    int port;    volatile __u16 *ptr;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return;    /* write the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	outw(data, port);    } else {	ptr = (__u16 *)(reg->mapped_ptr + offset);	*ptr = data;    }    return;}void upci_write_s16(int rd, __u32 offset, __s16 data){    struct region_info *reg;    int port;    volatile __s16 *ptr;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return;    /* write the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	outw(data, port);    } else {	ptr = (__s16 *)(reg->mapped_ptr + offset);	*ptr = data;    }    return;}void upci_write_u32(int rd, __u32 offset, __u32 data){    struct region_info *reg;    int port;    volatile __u32 *ptr;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return;    /* write the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	outl(data, port);    } else {	ptr = (__u32 *)(reg->mapped_ptr + offset);	*ptr = data;    }    return;}void upci_write_s32(int rd, __u32 offset, __s32 data){    struct region_info *reg;    int port;    volatile __s32 *ptr;    /* test for out of range, not mapped, or offset beyond end of region */    if ((rd < 0 ) || ( rd >= MAX_REGIONS ) ||	( (reg = regions[rd]) == NULL ) || ( offset > reg->size )) return;    /* write the data */    if ( reg->type == UPCI_REG_IO ) {	port = reg->base_addr + offset;	outl(data, port);    } else {	ptr = (__s32 *)(reg->mapped_ptr + offset);	*ptr = data;    }    return;}

⌨️ 快捷键说明

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