#include #include #include #include #include #include #include #include #include #define EISA_EEPROM_MINOR 241 static unsigned long eeprom_addr; static long long 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, char *buf, size_t count, loff_t *ppos ) { unsigned char *tmp; ssize_t ret; int i; loff_t n = *ppos; unsigned pos = n; if (n != pos || pos >= HPEE_MAX_LENGTH) return 0; if (count > HPEE_MAX_LENGTH - pos) count = HPEE_MAX_LENGTH - pos; tmp = kmalloc(count, GFP_KERNEL); if (tmp) { for (i = 0; i < count; i++) tmp[i] = gsc_readb(eeprom_addr+(pos)++); if (copy_to_user (buf, tmp, count)) ret = -EFAULT; else { ret = count; *ppos = pos; } kfree (tmp); } else ret = -ENOMEM; return ret; } static int eisa_eeprom_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return -ENOTTY; } static int eisa_eeprom_open(struct inode *inode, struct file *file) { if (file->f_mode & 2 || eeprom_addr == 0) return -EINVAL; return 0; } static int eisa_eeprom_release(struct inode *inode, struct file *file) { return 0; } /* * The various file operations we support. */ static struct file_operations eisa_eeprom_fops = { owner: THIS_MODULE, llseek: eisa_eeprom_llseek, read: eisa_eeprom_read, ioctl: eisa_eeprom_ioctl, open: eisa_eeprom_open, release: eisa_eeprom_release, }; static struct miscdevice eisa_eeprom_dev= { EISA_EEPROM_MINOR, "eisa eeprom", &eisa_eeprom_fops }; int __init eisa_eeprom_init(unsigned long addr) { if (addr) { eeprom_addr = addr; misc_register(&eisa_eeprom_dev); printk(KERN_INFO "EISA EEPROM at 0x%lx\n", eeprom_addr); } return 0; } MODULE_LICENSE("GPL");