linux/drivers/parisc/eisa_eeprom.c
<<
>>
Prefs
   1/* 
   2 *    EISA "eeprom" support routines
   3 *
   4 *    Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
   5 *
   6 *
   7 *    This program is free software; you can redistribute it and/or modify
   8 *    it under the terms of the GNU General Public License as published by
   9 *    the Free Software Foundation; either version 2 of the License, or
  10 *    (at your option) any later version.
  11 *
  12 *    This program is distributed in the hope that it will be useful,
  13 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 *    GNU General Public License for more details.
  16 *
  17 *    You should have received a copy of the GNU General Public License
  18 *    along with this program; if not, write to the Free Software
  19 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20 */
  21
  22#include <linux/module.h>
  23#include <linux/init.h>
  24#include <linux/kernel.h>
  25#include <linux/miscdevice.h>
  26#include <linux/slab.h>
  27#include <linux/fs.h>
  28#include <asm/io.h>
  29#include <asm/uaccess.h>
  30#include <asm/eisa_eeprom.h>
  31
  32#define         EISA_EEPROM_MINOR 241
  33
  34static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin)
  35{
  36        return fixed_size_llseek(file, offset, origin, HPEE_MAX_LENGTH);
  37}
  38
  39static ssize_t eisa_eeprom_read(struct file * file,
  40                              char __user *buf, size_t count, loff_t *ppos )
  41{
  42        unsigned char *tmp;
  43        ssize_t ret;
  44        int i;
  45        
  46        if (*ppos < 0 || *ppos >= HPEE_MAX_LENGTH)
  47                return 0;
  48        
  49        count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos;
  50        tmp = kmalloc(count, GFP_KERNEL);
  51        if (tmp) {
  52                for (i = 0; i < count; i++)
  53                        tmp[i] = readb(eisa_eeprom_addr+(*ppos)++);
  54
  55                if (copy_to_user (buf, tmp, count))
  56                        ret = -EFAULT;
  57                else
  58                        ret = count;
  59                kfree (tmp);
  60        } else
  61                ret = -ENOMEM;
  62        
  63        return ret;
  64}
  65
  66static int eisa_eeprom_open(struct inode *inode, struct file *file)
  67{
  68        if (file->f_mode & FMODE_WRITE)
  69                return -EINVAL;
  70   
  71        return 0;
  72}
  73
  74static int eisa_eeprom_release(struct inode *inode, struct file *file)
  75{
  76        return 0;
  77}
  78
  79/*
  80 *      The various file operations we support.
  81 */
  82static const struct file_operations eisa_eeprom_fops = {
  83        .owner =        THIS_MODULE,
  84        .llseek =       eisa_eeprom_llseek,
  85        .read =         eisa_eeprom_read,
  86        .open =         eisa_eeprom_open,
  87        .release =      eisa_eeprom_release,
  88};
  89
  90static struct miscdevice eisa_eeprom_dev = {
  91        EISA_EEPROM_MINOR,
  92        "eisa_eeprom",
  93        &eisa_eeprom_fops
  94};
  95
  96static int __init eisa_eeprom_init(void)
  97{
  98        int retval;
  99
 100        if (!eisa_eeprom_addr)
 101                return -ENODEV;
 102
 103        retval = misc_register(&eisa_eeprom_dev);
 104        if (retval < 0) {
 105                printk(KERN_ERR "EISA EEPROM: cannot register misc device.\n");
 106                return retval;
 107        }
 108
 109        printk(KERN_INFO "EISA EEPROM at 0x%p\n", eisa_eeprom_addr);
 110        return 0;
 111}
 112
 113MODULE_LICENSE("GPL");
 114
 115module_init(eisa_eeprom_init);
 116