diff options
author | John Crispin <john@openwrt.org> | 2007-12-14 23:23:10 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2007-12-14 23:23:10 +0000 |
commit | 880d600f7100ce3da5c87a7aa3dc03805334e09e (patch) | |
tree | 0622fe5d37ebd1d2fc362e64cbb90114133c7c03 /target/linux/danube/files/drivers/char/danube_eeprom.c | |
parent | cce622bcb8117e379447d7ebc55ec820e95e3c11 (diff) | |
download | upstream-880d600f7100ce3da5c87a7aa3dc03805334e09e.tar.gz upstream-880d600f7100ce3da5c87a7aa3dc03805334e09e.tar.bz2 upstream-880d600f7100ce3da5c87a7aa3dc03805334e09e.zip |
fix up eeprom and add ssc driver ... this needs a lot of work
SVN-Revision: 9761
Diffstat (limited to 'target/linux/danube/files/drivers/char/danube_eeprom.c')
-rw-r--r-- | target/linux/danube/files/drivers/char/danube_eeprom.c | 629 |
1 files changed, 293 insertions, 336 deletions
diff --git a/target/linux/danube/files/drivers/char/danube_eeprom.c b/target/linux/danube/files/drivers/char/danube_eeprom.c index 96fd777274..db0f610370 100644 --- a/target/linux/danube/files/drivers/char/danube_eeprom.c +++ b/target/linux/danube/files/drivers/char/danube_eeprom.c @@ -1,57 +1,31 @@ -/****************************************************************************** -** -** FILE NAME : danube_eeprom.c -** PROJECT : Danube -** MODULES : EEPROM -** -** DATE : 31 DEC 2004 -** AUTHOR : Liu Peng -** DESCRIPTION : X25040 EEPROM Driver -** COPYRIGHT : Copyright (c) 2006 -** Infineon Technologies AG -** Am Campeon 1-12, 85579 Neubiberg, Germany -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** HISTORY -** $Date $Author $Comment -** 31 DEC 2004 Liu Peng Initiate Version -** 25 OCT 2006 Xu Liang Add GPL header. -*******************************************************************************/ - -#define IFAP_EEPROM_DRV_VERSION "0.0.1" - /* - ************************************************** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This driver was originally based on the INCA-IP driver, but due to - * fundamental conceptual drawbacks there has been changed a lot. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn <gj@denx.de> - * Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This driver was originally based on the INCA-IP driver, but due to + * fundamental conceptual drawbacks there has been changed a lot. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn <gj@denx.de> + * Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Copyright (C) 2006 infineon + * Copyright (C) 2007 John Crispin <blogic@openwrt.org> * */ -#ifndef EXPORT_SYMTAB -#define EXPORT_SYMTAB -#endif -#include <linux/config.h> + +#define IFAP_EEPROM_DRV_VERSION "0.0.1" + #include <linux/module.h> #include <linux/errno.h> #include <linux/signal.h> @@ -61,7 +35,6 @@ #include <linux/major.h> #include <linux/string.h> #include <linux/fs.h> -#include <linux/proc_fs.h> #include <linux/fcntl.h> #include <linux/ptrace.h> #include <linux/mm.h> @@ -81,33 +54,15 @@ #include <linux/version.h> #include <asm/danube/danube.h> -#include <asm/danube/irq.h> +#include <asm/danube/danube_irq.h> #include <asm/danube/ifx_ssc_defines.h> #include <asm/danube/ifx_ssc.h> -#if CONFIG_MODVERSIONS==1 -# include <linux/modversions.h> -#endif - -#define AMAZON_EEPROM_EMSG(fmt,args...) printk("%s:" fmt, __FUNCTION__, ##args) - -#if 0 -#define AMAZON_EEPROM_DMSG(fmt,args...) printk("%s:" fmt, __FUNCTION__, ##args) -#else -#define AMAZON_EEPROM_DMSG(fmt,args...) -#endif - -MODULE_LICENSE ("GPL"); -MODULE_AUTHOR ("Peng Liu"); -MODULE_DESCRIPTION ("IFAP EEPROM driver"); -MODULE_SUPPORTED_DEVICE ("danube_eeprom"); -MODULE_PARM (maj, "i"); -MODULE_PARM_DESC (maj, "Major device number"); /* allow the user to set the major device number */ -static int maj = 0; +static int danube_eeprom_maj = 0; -static ssize_t danube_eeprom_read (struct file *, char *, size_t, loff_t *); -static ssize_t danube_eeprom_write (struct file *, const char *, size_t, +static ssize_t danube_eeprom_fops_read (struct file *, char *, size_t, loff_t *); +static ssize_t danube_eeprom_fops_write (struct file *, const char *, size_t, loff_t *); static int danube_eeprom_ioctl (struct inode *, struct file *, unsigned int, unsigned long); @@ -124,284 +79,277 @@ extern int ifx_ssc_ioctl (struct inode *inode, struct file *filp, extern ssize_t ifx_ssc_kwrite (int port, const char *kbuf, size_t len); extern ssize_t ifx_ssc_kread (int port, char *kbuf, size_t len); -extern int ifx_ssc_cs_low (u32 pin); -extern int ifx_ssc_cs_high (u32 pin); -extern int ifx_ssc_txrx (char *tx_buf, u32 tx_len, char *rx_buf, u32 rx_len); -extern int ifx_ssc_tx (char *tx_buf, u32 tx_len); -extern int ifx_ssc_rx (char *rx_buf, u32 rx_len); +extern int ifx_ssc_cs_low (unsigned int pin); +extern int ifx_ssc_cs_high (unsigned int pin); +extern int ifx_ssc_txrx (char *tx_buf, unsigned int tx_len, char *rx_buf, unsigned int rx_len); +extern int ifx_ssc_tx (char *tx_buf, unsigned int tx_len); +extern int ifx_ssc_rx (char *rx_buf, unsigned int rx_len); -/* CS: board dependant */ #define EEPROM_CS IFX_SSC_WHBGPOSTAT_OUT0_POS /* commands for EEPROM, x25160, x25140 */ -#define EEPROM_WREN ((u8)0x06) -#define EEPROM_WRDI ((u8)0x04) -#define EEPROM_RDSR ((u8)0x05) -#define EEPROM_WRSR ((u8)0x01) -#define EEPROM_READ ((u8)0x03) -#define EEPROM_WRITE ((u8)0x02) +#define EEPROM_WREN ((unsigned char)0x06) +#define EEPROM_WRDI ((unsigned char)0x04) +#define EEPROM_RDSR ((unsigned char)0x05) +#define EEPROM_WRSR ((unsigned char)0x01) +#define EEPROM_READ ((unsigned char)0x03) +#define EEPROM_WRITE ((unsigned char)0x02) #define EEPROM_PAGE_SIZE 4 #define EEPROM_SIZE 512 -/* Brief: EEPROM_RDSR command - * Return: 0 OK - * error code - */ static int eeprom_rdsr (char *status) { int ret = 0; unsigned char cmd = EEPROM_RDSR; - unsigned long flag; - local_irq_save (flag); - if ((ret = ifx_ssc_cs_low (EEPROM_CS))) { - local_irq_restore (flag); - return ret; + + local_irq_save(flag); + + if ((ret = ifx_ssc_cs_low (EEPROM_CS))) + { + local_irq_restore(flag); + goto out; } - if ((ret = ifx_ssc_txrx (&cmd, 1, status, 1)) < 0) { - ifx_ssc_cs_high (EEPROM_CS); - local_irq_restore (flag); - return ret; + + if ((ret = ifx_ssc_txrx (&cmd, 1, status, 1)) < 0) + { + ifx_ssc_cs_high(EEPROM_CS); + local_irq_restore(flag); + goto out; } - if ((ret = ifx_ssc_cs_high (EEPROM_CS))) { - local_irq_restore (flag); - return ret; + if ((ret = ifx_ssc_cs_high(EEPROM_CS))) + { + local_irq_restore(flag); + goto out; } - local_irq_restore (flag); + + local_irq_restore(flag); + +out: return ret; } -/* Brief: wait for WIP is over - * Return: - * 0 WIP is over - * <0 Error code - */ static inline int eeprom_wip_over (void) { int ret = 0; - u8 status; - while (1) { - ret = eeprom_rdsr (&status); - AMAZON_EEPROM_DMSG ("status %x \n", status); - if (ret) { - AMAZON_EEPROM_EMSG ("read back status fails %d\n", - ret); + unsigned char status; + + while (1) + { + ret = eeprom_rdsr(&status); + printk("status %x \n", status); + + if (ret) + { + printk("read back status fails %d\n", ret); break; } - else if (((status) & 1) != 0) { - AMAZON_EEPROM_DMSG ("read back status not zero %x\n", - status); - } - else { + + if (((status) & 1) != 0) + printk("read back status not zero %x\n", status); + else break; - } } + return ret; } -/* Brief: EEPROM_WREN command - * Return: 0 OK - * error code - */ static int eeprom_wren (void) { unsigned char cmd = EEPROM_WREN; int ret = 0; - unsigned long flag; - local_irq_save (flag); - if ((ret = ifx_ssc_cs_low (EEPROM_CS))) { - local_irq_restore (flag); - return ret; + + local_irq_save(flag); + if ((ret = ifx_ssc_cs_low(EEPROM_CS))) + { + local_irq_restore(flag); + goto out; } - if ((ret = ifx_ssc_tx (&cmd, 1)) < 0) { - ifx_ssc_cs_high (EEPROM_CS); - local_irq_restore (flag); - return ret; + if ((ret = ifx_ssc_tx(&cmd, 1)) < 0) + { + ifx_ssc_cs_high(EEPROM_CS); + local_irq_restore(flag); + goto out; } - if ((ret = ifx_ssc_cs_high (EEPROM_CS))) { - local_irq_restore (flag); - return ret; + if ((ret = ifx_ssc_cs_high(EEPROM_CS))) + { + local_irq_restore(flag); + goto out; } - local_irq_restore (flag); - eeprom_wip_over (); - return ret; + local_irq_restore(flag); + eeprom_wip_over(); + +out: + return ret; } -/* Brief: EEPROM_WRSR command - * Return: 0 OK - * error code - */ static int eeprom_wrsr (void) { int ret = 0; unsigned char cmd[2]; + unsigned long flag; + cmd[0] = EEPROM_WRSR; cmd[1] = 0; - if ((ret = eeprom_wren ())) { - AMAZON_EEPROM_EMSG ("eeprom_wren fails\n"); - return ret; - } - unsigned long flag; - local_irq_save (flag); - if ((ret = ifx_ssc_cs_low (EEPROM_CS))) { - goto eeprom_wrsr_err_out; - } - if ((ret = ifx_ssc_tx (cmd, 2)) < 0) { - ifx_ssc_cs_high (EEPROM_CS); - goto eeprom_wrsr_err_out; + if ((ret = eeprom_wren())) + { + printk ("eeprom_wren fails\n"); + goto out1; } - if ((ret = ifx_ssc_cs_low (EEPROM_CS))) { - goto eeprom_wrsr_err_out; + local_irq_save(flag); + + if ((ret = ifx_ssc_cs_low(EEPROM_CS))) + goto out; + + if ((ret = ifx_ssc_tx(cmd, 2)) < 0) { + ifx_ssc_cs_high(EEPROM_CS); + goto out; } - local_irq_restore (flag); - eeprom_wip_over (); + + if ((ret = ifx_ssc_cs_low(EEPROM_CS))) + goto out; + + local_irq_restore(flag); + eeprom_wip_over(); + return ret; - eeprom_wrsr_err_out: + +out: local_irq_restore (flag); eeprom_wip_over (); + +out1: return ret; } -/* Brief: read EEPROM - * Parameter: - * addr - * len - * buf - * Return: ok - * -EFAULT - */ static int -eeprom_read (u32 addr, unsigned char *buf, u32 len) +eeprom_read (unsigned int addr, unsigned char *buf, unsigned int len) { int ret = 0; unsigned char write_buf[2]; - u32 eff = 0; - + unsigned int eff = 0; unsigned long flag; - while (1) { - eeprom_wip_over (); + while (1) + { + eeprom_wip_over(); eff = EEPROM_PAGE_SIZE - (addr % EEPROM_PAGE_SIZE); eff = (eff < len) ? eff : len; - //Format: - //CMD + ADDR - local_irq_save (flag); - if ((ret = ifx_ssc_cs_low (EEPROM_CS)) < 0) { - goto eeprom_read_err_out; - } + local_irq_save(flag); + + if ((ret = ifx_ssc_cs_low(EEPROM_CS)) < 0) + goto out; - write_buf[0] = EEPROM_READ | ((u8) ((addr & 0x100) >> 5)); + write_buf[0] = EEPROM_READ | ((unsigned char) ((addr & 0x100) >> 5)); write_buf[1] = (addr & 0xff); - if ((ret = ifx_ssc_txrx (write_buf, 2, buf, eff)) != eff) { - AMAZON_EEPROM_EMSG ("ssc_txrx fails %d\n", ret); + if ((ret = ifx_ssc_txrx (write_buf, 2, buf, eff)) != eff) + { + printk("ssc_txrx fails %d\n", ret); ifx_ssc_cs_high (EEPROM_CS); - goto eeprom_read_err_out; + goto out; } + buf += ret; len -= ret; addr += ret; - if ((ret = ifx_ssc_cs_high (EEPROM_CS))) { - goto eeprom_read_err_out; - } - local_irq_restore (flag); - if (len <= 0) { - break; - } + + if ((ret = ifx_ssc_cs_high(EEPROM_CS))) + goto out; + + local_irq_restore(flag); + + if (len <= 0) + goto out2; } - return ret; - eeprom_read_err_out: +out: local_irq_restore (flag); +out2: return ret; } -/* Brief: write EEPROm - * Parameter: - * addr - * len - * buf - * Return: 0 ok - * -EFAULT - */ static int -eeprom_write (u32 addr, unsigned char *buf, u32 len) +eeprom_write (unsigned int addr, unsigned char *buf, unsigned int len) { int ret = 0; - u32 eff = 0; + unsigned int eff = 0; unsigned char write_buf[2]; + int i; + unsigned char rx_buf[EEPROM_PAGE_SIZE]; + + while (1) + { + eeprom_wip_over(); - //unsigned char rx_buf[EEPROM_PAGE_SIZE]; - //Format: - //CMD + ADDR + DATA (up to EEPROM_PAGE_SIZE) - while (1) { - eeprom_wip_over (); - if ((ret = eeprom_wren ())) { - AMAZON_EEPROM_EMSG ("eeprom_wren fails\n"); - return ret; + if ((ret = eeprom_wren())) + { + printk("eeprom_wren fails\n"); + goto out; } - write_buf[0] = EEPROM_WRITE | ((u8) ((addr & 0x100) >> 5)); + + write_buf[0] = EEPROM_WRITE | ((unsigned char) ((addr & 0x100) >> 5)); write_buf[1] = (addr & 0xff); eff = EEPROM_PAGE_SIZE - (addr % EEPROM_PAGE_SIZE); eff = (eff < len) ? eff : len; - AMAZON_EEPROM_DMSG ("EEPROM Write:\n"); -#if 0 - int i; + + printk("EEPROM Write:\n"); for (i = 0; i < eff; i++) { - printk ("%2x ", buf[i]); - if (i % 16 == 15) - printk ("\n"); + printk("%2x ", buf[i]); + if ((i % 16) == 15) + printk("\n"); } - printk ("\n"); -#endif + printk("\n"); - if ((ret = ifx_ssc_cs_low (EEPROM_CS))) { - return ret; - } + if ((ret = ifx_ssc_cs_low(EEPROM_CS))) + goto out; - if ((ret = ifx_ssc_tx (write_buf, 2)) < 0) { - AMAZON_EEPROM_EMSG ("ssc_tx fails %d\n", ret); - ifx_ssc_cs_high (EEPROM_CS); - return ret; + if ((ret = ifx_ssc_tx (write_buf, 2)) < 0) + { + printk("ssc_tx fails %d\n", ret); + ifx_ssc_cs_high(EEPROM_CS); + goto out; } - if ((ret = ifx_ssc_tx (buf, eff)) != eff) { - AMAZON_EEPROM_EMSG ("ssc_tx fails %d\n", ret); - ifx_ssc_cs_high (EEPROM_CS); - return ret; + if ((ret = ifx_ssc_tx (buf, eff)) != eff) + { + printk("ssc_tx fails %d\n", ret); + ifx_ssc_cs_high(EEPROM_CS); + goto out; } buf += ret; len -= ret; addr += ret; - if ((ret = ifx_ssc_cs_high (EEPROM_CS))) { - return ret; - } -#if 0 + if ((ret = ifx_ssc_cs_high (EEPROM_CS))) + goto out; + printk ("<=="); - eeprom_read ((addr - eff), rx_buf, eff); - for (i = 0; i < eff; i++) { + eeprom_read((addr - eff), rx_buf, eff); + for (i = 0; i < eff; i++) + { printk ("[%x]", rx_buf[i]); } printk ("\n"); -#endif + if (len <= 0) break; } +out: return ret; } @@ -419,139 +367,156 @@ danube_eeprom_close (struct inode *inode, struct file *filp) } int -danube_eeprom_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long data) +danube_eeprom_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) { return 0; } ssize_t -danube_eeprom_kread (char *buf, size_t len, u32 addr) +danube_eeprom_read (char *buf, size_t len, unsigned int addr) { int ret = 0; - u32 data; - printk ("addr:=%d\n", addr); - printk ("len:=%d\n", len); - if ((addr + len) > EEPROM_SIZE) { - AMAZON_EEPROM_EMSG ("invalid len\n"); + unsigned int data; + + printk("addr:=%d\n", addr); + printk("len:=%d\n", len); + + if ((addr + len) > EEPROM_SIZE) + { + printk("invalid len\n"); addr = 0; len = EEPROM_SIZE / 2; } - if ((ret = ifx_ssc_open ((struct inode *) 0, NULL))) { - AMAZON_EEPROM_EMSG ("danube_eeprom_open fails\n"); - goto read_err_out; + if ((ret = ifx_ssc_open ((struct inode *) 0, NULL))) + { + printk("danube_eeprom_open fails\n"); + goto out; } - data = (u32) IFX_SSC_MODE_RXTX; - if ((ret = - ifx_ssc_ioctl ((struct inode *) 0, NULL, IFX_SSC_RXTX_MODE_SET, - (unsigned long) &data))) { - AMAZON_EEPROM_EMSG ("set RXTX mode fails\n"); - goto read_err_out; - } + data = (unsigned int)IFX_SSC_MODE_RXTX; - if ((ret = eeprom_wrsr ())) { - AMAZON_EEPROM_EMSG ("EEPROM reset fails\n"); - goto read_err_out; + if ((ret = ifx_ssc_ioctl ((struct inode *) 0, NULL, IFX_SSC_RXTX_MODE_SET, (unsigned long) &data))) + { + printk("set RXTX mode fails\n"); + goto out; } - if ((ret = eeprom_read (addr, buf, len))) { - AMAZON_EEPROM_EMSG ("eeprom read fails\n"); - goto read_err_out; + if ((ret = eeprom_wrsr ())) + { + printk("EEPROM reset fails\n"); + goto out; } - read_err_out: - if (ifx_ssc_close ((struct inode *) 0, NULL)) { - AMAZON_EEPROM_EMSG ("danube_eeprom_close fails\n"); + if ((ret = eeprom_read (addr, buf, len))) + { + printk("eeprom read fails\n"); + goto out; } - return len; -} +out: + if (ifx_ssc_close ((struct inode *) 0, NULL)) + printk("danube_eeprom_close fails\n"); -EXPORT_SYMBOL (danube_eeprom_kread); + return len; +} +EXPORT_SYMBOL(danube_eeprom_read); static ssize_t -danube_eeprom_read (struct file *filp, char *ubuf, size_t len, loff_t * off) +danube_eeprom_fops_read (struct file *filp, char *ubuf, size_t len, loff_t * off) { int ret = 0; unsigned char ssc_rx_buf[EEPROM_SIZE]; long flag; + if (*off >= EEPROM_SIZE) return 0; + if (*off + len > EEPROM_SIZE) len = EEPROM_SIZE - *off; + if (len == 0) return 0; - local_irq_save (flag); - if ((ret = danube_eeprom_kread (ssc_rx_buf, len, *off)) < 0) { - AMAZON_EEPROM_EMSG ("read fails, err=%x\n", ret); - local_irq_restore (flag); + + local_irq_save(flag); + + if ((ret = danube_eeprom_read(ssc_rx_buf, len, *off)) < 0) + { + printk("read fails, err=%x\n", ret); + local_irq_restore(flag); return ret; } - if (copy_to_user ((void *) ubuf, ssc_rx_buf, ret) != 0) { - local_irq_restore (flag); + + if (copy_to_user((void*)ubuf, ssc_rx_buf, ret) != 0) + { + local_irq_restore(flag); ret = -EFAULT; } - local_irq_restore (flag); + + local_irq_restore(flag); *off += len; + return len; } ssize_t -danube_eeprom_kwrite (char *buf, size_t len, u32 addr) +danube_eeprom_write (char *buf, size_t len, unsigned int addr) { int ret = 0; - u32 data; - if ((ret = ifx_ssc_open ((struct inode *) 0, NULL))) { - AMAZON_EEPROM_EMSG ("danube_eeprom_open fails\n"); - goto write_err_out; + unsigned int data; + + if ((ret = ifx_ssc_open ((struct inode *) 0, NULL))) + { + printk ("danube_eeprom_open fails\n"); + goto out; } - data = (u32) IFX_SSC_MODE_RXTX; - if ((ret = - ifx_ssc_ioctl ((struct inode *) 0, NULL, IFX_SSC_RXTX_MODE_SET, - (unsigned long) &data))) { - AMAZON_EEPROM_EMSG ("set RXTX mode fails\n"); - goto write_err_out; + data = (unsigned int) IFX_SSC_MODE_RXTX; + + if ((ret = ifx_ssc_ioctl ((struct inode *) 0, NULL, IFX_SSC_RXTX_MODE_SET, (unsigned long) &data))) + { + printk ("set RXTX mode fails\n"); + goto out; } if ((ret = eeprom_wrsr ())) { - AMAZON_EEPROM_EMSG ("EEPROM reset fails\n"); - goto write_err_out; + printk ("EEPROM reset fails\n"); + goto out; } if ((ret = eeprom_write (addr, buf, len))) { - AMAZON_EEPROM_EMSG ("eeprom write fails\n"); - goto write_err_out; + printk ("eeprom write fails\n"); + goto out; } - write_err_out: - if (ifx_ssc_close ((struct inode *) 0, NULL)) { - AMAZON_EEPROM_EMSG ("danube_eeprom_close fails\n"); - } +out: + if (ifx_ssc_close ((struct inode *) 0, NULL)) + printk ("danube_eeprom_close fails\n"); + return ret; } - -EXPORT_SYMBOL (danube_eeprom_kwrite); +EXPORT_SYMBOL(danube_eeprom_write); static ssize_t -danube_eeprom_write (struct file *filp, const char *ubuf, size_t len, - loff_t * off) +danube_eeprom_fops_write (struct file *filp, const char *ubuf, size_t len, loff_t * off) { int ret = 0; unsigned char ssc_tx_buf[EEPROM_SIZE]; + if (*off >= EEPROM_SIZE) return 0; + if (len + *off > EEPROM_SIZE) len = EEPROM_SIZE - *off; - if ((ret = copy_from_user (ssc_tx_buf, ubuf, len))) { + + if ((ret = copy_from_user (ssc_tx_buf, ubuf, len))) return EFAULT; - } - ret = danube_eeprom_kwrite (ssc_tx_buf, len, *off); - if (ret > 0) { + + ret = danube_eeprom_write (ssc_tx_buf, len, *off); + + if (ret > 0) *off = ret; - } + return ret; } @@ -560,33 +525,34 @@ danube_eeprom_llseek (struct file * filp, loff_t off, int whence) { loff_t newpos; switch (whence) { - case 0: /*SEEK_SET */ + case SEEK_SET: newpos = off; break; - case 1: /*SEEK_CUR */ + + case SEEK_CUR: newpos = filp->f_pos + off; break; + default: return -EINVAL; } + if (newpos < 0) return -EINVAL; + filp->f_pos = newpos; + return newpos; } static struct file_operations danube_eeprom_fops = { owner:THIS_MODULE, llseek:danube_eeprom_llseek, - /* llseek */ - read:danube_eeprom_read, /* read */ - write:danube_eeprom_write, - /* write */ + read:danube_eeprom_fops_read, + write:danube_eeprom_fops_write, ioctl:danube_eeprom_ioctl, - /* ioctl */ - open:danube_eeprom_open, /* open */ + open:danube_eeprom_open, release:danube_eeprom_close, - /* release */ }; int __init @@ -594,46 +560,37 @@ danube_eeprom_init (void) { int ret = 0; - if ((ret = register_chrdev (maj, "eeprom", &danube_eeprom_fops)) < 0) { - printk ("Unable to register major %d for the Infineon Amazon EEPROM\n", maj); - if (maj == 0) { - goto errout; - } - else { - maj = 0; - if ((ret = - register_chrdev (maj, "ssc", - &danube_eeprom_fops)) < 0) { - printk ("Unable to register major 0 for the Infineon Amazon EEPROM\n"); - goto errout; - } - } + danube_eeprom_maj = register_chrdev(0, "eeprom", &danube_eeprom_fops); + + if (danube_eeprom_maj < 0) + { + printk("failed to register eeprom device\n"); + ret = -EINVAL; + + goto out; } - if (maj == 0) - maj = ret; - errout: + + printk("danube_eeprom : /dev/eeprom mayor %d\n", danube_eeprom_maj); + +out: return ret; } void __exit danube_eeprom_cleanup_module (void) { - if (unregister_chrdev (maj, "eeprom")) { + /*if (unregister_chrdev (danube_eeprom_maj, "eeprom")) { printk ("Unable to unregister major %d for the EEPROM\n", maj); - } + }*/ } module_exit (danube_eeprom_cleanup_module); module_init (danube_eeprom_init); -#ifndef MODULE -static int __init -danube_eeprom_set_maj (char *str) -{ - maj = simple_strtol (str, NULL, 0); - return 1; -} +MODULE_LICENSE ("GPL"); +MODULE_AUTHOR ("Peng Liu"); +MODULE_DESCRIPTION ("IFAP EEPROM driver"); +MODULE_SUPPORTED_DEVICE ("danube_eeprom"); + -__setup ("eeprom_maj=", danube_eeprom_set_maj); -#endif /* !MODULE */ |