added mtd driver
[linux-2.4.git] / drivers / gsc / eisa_eeprom.c
1 #include <linux/config.h>
2 #include <linux/module.h>
3 #include <linux/init.h>
4 #include <linux/kernel.h>
5 #include <linux/miscdevice.h>
6 #include <linux/slab.h>
7 #include <asm/gsc.h>
8 #include <asm/uaccess.h>
9 #include <asm/eisa_eeprom.h>
10
11 #define         EISA_EEPROM_MINOR 241
12
13 static unsigned long eeprom_addr;
14
15 static long long eisa_eeprom_llseek(struct file *file, loff_t offset, int origin )
16 {
17         switch (origin) {
18           case 0:
19                 /* nothing to do */
20                 break;
21           case 1:
22                 offset += file->f_pos;
23                 break;
24           case 2:
25                 offset += HPEE_MAX_LENGTH;
26                 break;
27         }
28         return (offset >= 0 && offset < HPEE_MAX_LENGTH) ? (file->f_pos = offset) : -EINVAL;
29 }
30
31 static ssize_t eisa_eeprom_read(struct file * file,
32                               char *buf, size_t count, loff_t *ppos )
33 {
34         unsigned char *tmp;
35         ssize_t ret;
36         int i;
37         loff_t n = *ppos;
38         unsigned pos = n;
39         
40         if (n != pos || pos >= HPEE_MAX_LENGTH)
41                 return 0;
42         
43         if (count > HPEE_MAX_LENGTH - pos)
44                 count = HPEE_MAX_LENGTH - pos;
45
46         tmp = kmalloc(count, GFP_KERNEL);
47         if (tmp) {
48                 for (i = 0; i < count; i++)
49                         tmp[i] = gsc_readb(eeprom_addr+(pos)++);
50
51                 if (copy_to_user (buf, tmp, count))
52                         ret = -EFAULT;
53                 else {
54                         ret = count;
55                         *ppos = pos;
56                 }
57                 kfree (tmp);
58         } else
59                 ret = -ENOMEM;
60
61         return ret;
62 }
63
64 static int eisa_eeprom_ioctl(struct inode *inode, struct file *file, 
65                            unsigned int cmd,
66                            unsigned long arg)
67 {
68         return -ENOTTY;
69 }
70
71 static int eisa_eeprom_open(struct inode *inode, struct file *file)
72 {
73         if (file->f_mode & 2 || eeprom_addr == 0)
74                 return -EINVAL;
75    
76         return 0;
77 }
78
79 static int eisa_eeprom_release(struct inode *inode, struct file *file)
80 {
81         return 0;
82 }
83
84 /*
85  *      The various file operations we support.
86  */
87 static struct file_operations eisa_eeprom_fops = {
88         owner:          THIS_MODULE,
89         llseek:         eisa_eeprom_llseek,
90         read:           eisa_eeprom_read,
91         ioctl:          eisa_eeprom_ioctl,
92         open:           eisa_eeprom_open,
93         release:        eisa_eeprom_release,
94 };
95
96 static struct miscdevice eisa_eeprom_dev=
97 {
98         EISA_EEPROM_MINOR,
99         "eisa eeprom",
100         &eisa_eeprom_fops
101 };
102
103 int __init eisa_eeprom_init(unsigned long addr)
104 {
105         if (addr) {
106                 eeprom_addr = addr;
107                 misc_register(&eisa_eeprom_dev);
108                 printk(KERN_INFO "EISA EEPROM at 0x%lx\n", eeprom_addr);
109         }
110         return 0;
111 }
112
113 MODULE_LICENSE("GPL");