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

📄 tpam_memory.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
字号:
/* $Id: tpam_memory.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - Board Memory Access) * * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alc魐e * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * * For all support questions please contact: <support@auvertech.fr> * */#include <linux/pci.h>#include <asm/io.h>#include "tpam.h"/* * Write a DWORD into the board memory. * * 	card: the board * 	addr: the address (in the board memory) * 	val: the value to put into the memory. */void copy_to_pam_dword(tpam_card *card, const void *addr, u32 val) {	/* set the page register */	writel(((unsigned long)addr) | TPAM_PAGE_SIZE, 	       card->bar0 + TPAM_PAGE_REGISTER);	/* write the value */	writel(val, card->bar0 + (((u32)addr) & TPAM_PAGE_SIZE));}/* * Write n bytes into the board memory. The count of bytes will be rounded * up to a multiple of 4. * * 	card: the board * 	to: the destination address (in the board memory) * 	from: the source address (in the kernel memory) * 	n: number of bytes */void copy_to_pam(tpam_card *card, void *to, const void *from, u32 n) {	u32 page, offset, count;	/* need to write in dword ! */	while (n & 3) n++;	while (n) {		page = ((u32)to) | TPAM_PAGE_SIZE;		offset = ((u32)to) & TPAM_PAGE_SIZE;		count = n < TPAM_PAGE_SIZE - offset				? n				: TPAM_PAGE_SIZE - offset;		/* set the page register */		writel(page, card->bar0 + TPAM_PAGE_REGISTER);		/* copy the data */		memcpy_toio((void *)(card->bar0 + offset), from, count);				from += count;		to += count;		n -= count;	}}/* * Read a DWORD from the board memory. * * 	card: the board * 	addr: the address (in the board memory) * * Return: the value read into the memory. */u32 copy_from_pam_dword(tpam_card *card, const void *addr) {	/* set the page register */	writel(((u32)addr) | TPAM_PAGE_SIZE, 	       card->bar0 + TPAM_PAGE_REGISTER);	/* read the data */	return readl(card->bar0 + (((u32)addr) & TPAM_PAGE_SIZE));}/* * Read n bytes from the board memory. * * 	card: the board * 	to: the destination address (in the kernel memory) * 	from: the source address (in the board memory) * 	n: number of bytes */void copy_from_pam(tpam_card *card, void *to, const void *from, u32 n) {	u32 page, offset, count;	while (n) {		page = ((u32)from) | TPAM_PAGE_SIZE;		offset = ((u32)from) & TPAM_PAGE_SIZE;		count = n < TPAM_PAGE_SIZE - offset 				? n 				: TPAM_PAGE_SIZE - offset;		/* set the page register */		writel(page, card->bar0 + TPAM_PAGE_REGISTER);		/* read the data */		memcpy_fromio(to, (void *)(card->bar0 + offset), count);				from += count;		to += count;		n -= count;	}}/* * Read n bytes from the board memory and writes them into the user memory. * * 	card: the board * 	to: the destination address (in the userspace memory) * 	from: the source address (in the board memory) * 	n: number of bytes * * Return: 0 if OK, <0 if error. */int copy_from_pam_to_user(tpam_card *card, void *to, const void *from, u32 n) {	void *page;	u32 count;	/* allocate a free page for the data transfer */	if (!(page = (void *)__get_free_page(GFP_KERNEL))) {		printk(KERN_ERR "TurboPAM(copy_from_pam_to_user): "		       "get_free_page failed\n");		return -ENOMEM;	}	while (n) {		count = n < PAGE_SIZE ? n : PAGE_SIZE;		/* copy data from the board into the kernel memory */		spin_lock_irq(&card->lock);		copy_from_pam(card, page, from, count);		spin_unlock_irq(&card->lock);		/* copy it from the kernel memory into the user memory */		if (copy_to_user(to, page, count)) {						/* this can fail... */			free_page((u32)page);			return -EFAULT;		}		from += count;		to += count;		n -= count;	}	/* release allocated memory */	free_page((u32)page);	return 0;}/* * Read n bytes from the user memory and writes them into the board memory. * * 	card: the board * 	to: the destination address (in the board memory) * 	from: the source address (in the userspace memory) * 	n: number of bytes * * Return: 0 if OK, <0 if error. */int copy_from_user_to_pam(tpam_card *card, void *to, const void *from, u32 n) {	void *page;	u32 count;	/* allocate a free page for the data transfer */	if (!(page = (void *)__get_free_page(GFP_KERNEL))) {		printk(KERN_ERR "TurboPAM(copy_from_user_to_pam): "		       "get_free_page failed\n");		return -ENOMEM;	}	while (n) {		count = n < PAGE_SIZE ? n : PAGE_SIZE;		/* copy data from the user memory into the kernel memory */		if (copy_from_user(page, from, count)) {			/* this can fail... */			free_page((u32)page);			return -EFAULT;		}		/* copy it from the kernel memory into the board memory */		spin_lock_irq(&card->lock);		copy_to_pam(card, to, page, count);		spin_unlock_irq(&card->lock);		from += count;		to += count;		n -= count;	}	/* release allocated memory */	free_page((u32)page);	return 0;}/* * Verify if we have the permission to read or writes len bytes at the * address address from/to the board memory. * * 	address: the start address (in the board memory) * 	len: number of bytes * * Return: 0 if OK, <0 if error. */int tpam_verify_area(u32 address, u32 len) {	if (address < TPAM_RESERVEDAREA1_START)		return (address + len <= TPAM_RESERVEDAREA1_START) ? 0 : -1;	if (address <= TPAM_RESERVEDAREA1_END)		return -1;	if (address < TPAM_RESERVEDAREA2_START)		return (address + len <= TPAM_RESERVEDAREA2_START) ? 0 : -1;	if (address <= TPAM_RESERVEDAREA2_END)		return -1;	if (address < TPAM_RESERVEDAREA3_START)		return (address + len <= TPAM_RESERVEDAREA3_START) ? 0 : -1;	if (address <= TPAM_RESERVEDAREA3_END)		return -1;	if (address < TPAM_RESERVEDAREA4_START)		return (address + len <= TPAM_RESERVEDAREA4_START) ? 0 : -1;	if (address <= TPAM_RESERVEDAREA4_END)		return -1;	return 0;}

⌨️ 快捷键说明

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