2005-04-17 02:20:36 +04:00
/*
* EISA " eeprom " support routines
*
* Copyright ( C ) 2001 Thomas Bogendoerfer < tsbogend at parisc - linux . org >
*
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/miscdevice.h>
# include <linux/slab.h>
# include <linux/fs.h>
# include <asm/io.h>
# include <asm/uaccess.h>
# include <asm/eisa_eeprom.h>
# define EISA_EEPROM_MINOR 241
static loff_t eisa_eeprom_llseek ( struct file * file , loff_t offset , int origin )
{
switch ( origin ) {
case 0 :
/* nothing to do */
break ;
case 1 :
offset + = file - > f_pos ;
break ;
case 2 :
offset + = HPEE_MAX_LENGTH ;
break ;
}
return ( offset > = 0 & & offset < HPEE_MAX_LENGTH ) ? ( file - > f_pos = offset ) : - EINVAL ;
}
static ssize_t eisa_eeprom_read ( struct file * file ,
2006-01-11 04:47:51 +03:00
char __user * buf , size_t count , loff_t * ppos )
2005-04-17 02:20:36 +04:00
{
unsigned char * tmp ;
ssize_t ret ;
int i ;
2009-07-21 02:58:44 +04:00
if ( * ppos < 0 | | * ppos > = HPEE_MAX_LENGTH )
2005-04-17 02:20:36 +04:00
return 0 ;
count = * ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - * ppos ;
tmp = kmalloc ( count , GFP_KERNEL ) ;
if ( tmp ) {
for ( i = 0 ; i < count ; i + + )
tmp [ i ] = readb ( eisa_eeprom_addr + ( * ppos ) + + ) ;
if ( copy_to_user ( buf , tmp , count ) )
ret = - EFAULT ;
else
ret = count ;
kfree ( tmp ) ;
} else
ret = - ENOMEM ;
return ret ;
}
static int eisa_eeprom_open ( struct inode * inode , struct file * file )
{
2008-09-02 23:28:45 +04:00
if ( file - > f_mode & FMODE_WRITE )
2005-04-17 02:20:36 +04:00
return - EINVAL ;
return 0 ;
}
static int eisa_eeprom_release ( struct inode * inode , struct file * file )
{
return 0 ;
}
/*
* The various file operations we support .
*/
2007-02-12 11:55:34 +03:00
static const struct file_operations eisa_eeprom_fops = {
2005-04-17 02:20:36 +04:00
. owner = THIS_MODULE ,
. llseek = eisa_eeprom_llseek ,
. read = eisa_eeprom_read ,
. open = eisa_eeprom_open ,
. release = eisa_eeprom_release ,
} ;
static struct miscdevice eisa_eeprom_dev = {
EISA_EEPROM_MINOR ,
" eisa_eeprom " ,
& eisa_eeprom_fops
} ;
static int __init eisa_eeprom_init ( void )
{
int retval ;
if ( ! eisa_eeprom_addr )
return - ENODEV ;
retval = misc_register ( & eisa_eeprom_dev ) ;
if ( retval < 0 ) {
printk ( KERN_ERR " EISA EEPROM: cannot register misc device. \n " ) ;
return retval ;
}
printk ( KERN_INFO " EISA EEPROM at 0x%p \n " , eisa_eeprom_addr ) ;
return 0 ;
}
MODULE_LICENSE ( " GPL " ) ;
module_init ( eisa_eeprom_init ) ;