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
eisa_eeprom_llseek(struct file * file,loff_t offset,int origin)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
eisa_eeprom_read(struct file * file,char * buf,size_t count,loff_t * ppos)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
eisa_eeprom_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)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
eisa_eeprom_open(struct inode * inode,struct file * file)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
eisa_eeprom_release(struct inode * inode,struct file * file)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
eisa_eeprom_init(unsigned long addr)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");
114