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/smp_lock.h>
  28#include <linux/fs.h>
  29#include <asm/io.h>
  30#include <asm/uaccess.h>
  31#include <asm/eisa_eeprom.h>
  32
  33#define         EISA_EEPROM_MINOR 241
  34
  35static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin )
  36{
  37        switch (origin) {
  38          case 0:
  39                /* nothing to do */
  40                break;
  41          case 1:
  42                offset += file->f_pos;
  43                break;
  44          case 2:
  45                offset += HPEE_MAX_LENGTH;
  46                break;
  47        }
  48        return (offset >= 0 && offset < HPEE_MAX_LENGTH) ? (file->f_pos = offset) : -EINVAL;
  49}
  50
  51static ssize_t eisa_eeprom_read(struct file * file,
  52                              char __user *buf, size_t count, loff_t *ppos )
  53{
  54        unsigned char *tmp;
  55        ssize_t ret;
  56        int i;
  57        
  58        if (*ppos < 0 || *ppos >= HPEE_MAX_LENGTH)
  59                return 0;
  60        
  61        count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos;
  62        tmp = kmalloc(count, GFP_KERNEL);
  63        if (tmp) {
  64                for (i = 0; i < count; i++)
  65                        tmp[i] = readb(eisa_eeprom_addr+(*ppos)++);
  66
  67                if (copy_to_user (buf, tmp, count))
  68                        ret = -EFAULT;
  69                else
  70                        ret = count;
  71                kfree (tmp);
  72        } else
  73                ret = -ENOMEM;
  74        
  75        return ret;
  76}
  77
  78static int eisa_eeprom_ioctl(struct inode *inode, struct file *file, 
  79                           unsigned int cmd,
  80                           unsigned long arg)
  81{
  82        return -ENOTTY;
  83}
  84
  85static int eisa_eeprom_open(struct inode *inode, struct file *file)
  86{
  87        cycle_kernel_lock();
  88
  89        if (file->f_mode & FMODE_WRITE)
  90                return -EINVAL;
  91   
  92        return 0;
  93}
  94
  95static int eisa_eeprom_release(struct inode *inode, struct file *file)
  96{
  97        return 0;
  98}
  99
 100/*
 101 *      The various file operations we support.
 102 */
 103static const struct file_operations eisa_eeprom_fops = {
 104        .owner =        THIS_MODULE,
 105        .llseek =       eisa_eeprom_llseek,
 106        .read =         eisa_eeprom_read,
 107        .ioctl =        eisa_eeprom_ioctl,
 108        .open =         eisa_eeprom_open,
 109        .release =      eisa_eeprom_release,
 110};
 111
 112static struct miscdevice eisa_eeprom_dev = {
 113        EISA_EEPROM_MINOR,
 114        "eisa_eeprom",
 115        &eisa_eeprom_fops
 116};
 117
 118static int __init eisa_eeprom_init(void)
 119{
 120        int retval;
 121
 122        if (!eisa_eeprom_addr)
 123                return -ENODEV;
 124
 125        retval = misc_register(&eisa_eeprom_dev);
 126        if (retval < 0) {
 127                printk(KERN_ERR "EISA EEPROM: cannot register misc device.\n");
 128                return retval;
 129        }
 130
 131        printk(KERN_INFO "EISA EEPROM at 0x%p\n", eisa_eeprom_addr);
 132        return 0;
 133}
 134
 135MODULE_LICENSE("GPL");
 136
 137module_init(eisa_eeprom_init);
 138