/*
 *                     OpenBIOS - free your system! 
 *              ( firmware/flash device driver for Linux )
 *                          
 *  filesystem.c - vfs character device interface
 *  
 *  This program is part of a free implementation of the IEEE 1275-1994 
 *  Standard for Boot (Initialization Configuration) Firmware.
 *
 *  Copyright (C) 1998-2004  Stefan Reinauer
 *
 *  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; version 2 of the License.
 *
 *  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.
 *
 *  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., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
 *
 */

#include <linux/config.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) && defined(MODVERSIONS)
#include <linux/modversions.h>
#endif
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <linux/fcntl.h>
#include <linux/delay.h>

#include <asm/uaccess.h>

#include "bios.h"
#include "flashchips.h"
#include "pcisets.h"
#include "programming.h"

#ifdef MODULE
void inc_mod(void);
void dec_mod(void);
#endif

/*
 * ******************************************
 *
 *	/dev/bios filesystem operations
 *
 * ****************************************** 
 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define FDEV		(MINOR(file->f_dentry->d_inode->i_rdev))
#else
#define FDEV		(iminor(file->f_dentry->d_inode))
#endif
#define CFLASH		flashdevices[FDEV]
// #define BIOS_SIZE	((flashchips[CFLASH.flashnum].size)*1024)
#define BIOS_SIZE	(CFLASH.size)

static loff_t bios_llseek(struct file *file, loff_t offset, int origin )
{
	currflash=FDEV;
	switch(origin) {
	  case 0:
		break;
	  case 1:
		offset += file->f_pos;
		break;
	  case 2:
		offset += BIOS_SIZE;
		break;
	}
	return((offset >= 0)?(file->f_pos = offset):-EINVAL);
}

static ssize_t bios_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
{
	signed int size=((BIOS_SIZE-*ppos>count) ? count : BIOS_SIZE-*ppos);
	unsigned char *addr = (unsigned char*)CFLASH.mapped + CFLASH.offset;
	int i;

	currflash = FDEV;

	devices[flashdevices[currflash].idx].activate();

	for (i=0;i<size;i++) 
		buffer[i]=flash_readb(addr,*ppos+i);

	devices[flashdevices[currflash].idx].deactivate();

	*ppos+=size;
	return size;
}

static ssize_t bios_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
{
        unsigned long flags;
	unsigned int offset=0, startsec=0, endsec=0;
	unsigned int secnum=0, size=0, writeoffs=0;
	unsigned int i, fn;
	unsigned char *clipboard;
	unsigned char *addr = (unsigned char*)CFLASH.mapped + CFLASH.offset;

	currflash=FDEV;
	fn=CFLASH.flashnum;

	/* Some security checks. */

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
	if (!suser())
		return -EACCES;
#endif

	if (!write) {
		printk (KERN_WARNING "Writing is disabled for security reasons.  RTFM.\n");
		return -EACCES;
	}

	if (!flashchips[fn].supported) {
		printk (KERN_ERR "BIOS: Flash device not supported.\n");
		return -EMEDIUMTYPE;
	}

	if ( count > BIOS_SIZE-*ppos )
		return -EFBIG;

	/* FIXME: Autoselect(AMD) BC-90 
	 * -> 00/MID; 
	 *    01/PID; 
	 *    02/Protected (1=yes/0=no)
	 */

	/* Determine size of data to be written */

	if (!(flashchips[fn].flags & f_needs_erase) ) {
		offset=(unsigned int)*ppos&~(flashchips[fn].pagesize-1);
		size=(((unsigned int)*ppos+count+(flashchips[fn].pagesize-1))&
				~(flashchips[CFLASH.flashnum].pagesize-1))-offset;
	} else {
		while (flashchips[fn].sectors[secnum] <= flashchips[fn].size ) {
			if ((unsigned int)*ppos >= flashchips[fn].sectors[secnum]*1024) {
				offset=flashchips[fn].sectors[secnum]*1024;
				startsec=secnum;
			}
			if ((unsigned int)*ppos+count-1 <= flashchips[fn].sectors[secnum]*1024) {
				size=(flashchips[fn].sectors[secnum]*1024)-offset;
				endsec=secnum-1;
				break;
			}
			secnum++;
		}
	}

#ifdef DEBUG
	printk (KERN_DEBUG "BIOS: Write [0x%06x..0x%06x] [0x%06x..0x%06x]\n",
			(unsigned int)(*ppos),(unsigned int)(*ppos+count-1),offset,offset+size-1);
#endif

	/* prepare data for writing */

	clipboard=vmalloc(size);

	spin_lock_irqsave(&bios_lock, flags);

	devices[flashdevices[currflash].idx].activate();

	for (i=0; i < size; i++) 
		clipboard[i] = flash_readb(addr,offset+i);

	copy_from_user(clipboard+(*ppos-offset), buffer, count);

	/* start write access */

	if (flashchips[fn].flags & f_intel_compl) {
		iflash_erase_sectors(addr,fn,startsec,endsec);

		for (i=0;i<size;i++)
			iflash_program_byte(addr, offset+i, clipboard[i]);

		flash_command(addr, 0xff);

	} else {

	  if (flashchips[fn].flags & f_needs_erase) {
	    if (size == flashchips[fn].size*1024) { /* whole chip erase */
	      printk (KERN_DEBUG "BIOS: Erasing via whole chip method\n");
	      flash_erase(addr, fn);
	    } else {
	      printk (KERN_DEBUG "BIOS: Erasing via sector method\n");
	      flash_erase_sectors(addr, fn,startsec,endsec);
	    }
	  } 

	  while (size>0) {
	    if ((flashchips[fn].flags & f_manuf_compl) != f_atmel_compl) {
	      flash_program(addr);
	    } else {
	      flash_program_atmel(addr);
	    }
	    for (i=0;i<flashchips[fn].pagesize;i++) {
	      flash_writeb(addr,offset+writeoffs+i,clipboard[writeoffs+i]);
	    }
	    if ((flashchips[fn].flags & f_manuf_compl) == f_atmel_compl) {
	      udelay(750);
	    } else {
		    if (flashchips[fn].pagesize==1)
			    udelay(30);
	 	    else
	      		    udelay(300);
	    }

	    if (flash_ready_poll(addr,offset+writeoffs+flashchips[fn].pagesize-1,
				 clipboard[writeoffs+flashchips[fn].pagesize-1])) {
	      printk (KERN_ERR "BIOS: Error occurred, please repeat write operation.\n");
	    }
	    flash_command(addr, 0xf0);
	    
	    writeoffs += flashchips[fn].pagesize;
	    size	  -= flashchips[fn].pagesize;
	  }
	}

	devices[flashdevices[currflash].idx].deactivate();

	spin_unlock_irqrestore(&bios_lock, flags);

	vfree(clipboard);

	*ppos+=count;
	return count;
}

static int bios_open(struct inode *inode, struct file *file)
{
	currflash=FDEV;
	
	if (flashcount<=FDEV) {
		printk (KERN_ERR "BIOS: There is no device (%d).\n",FDEV);
		return -ENODEV;
	}

#ifdef DEBUG
	printk(KERN_DEBUG "BIOS: Opening device %d\n",FDEV);
#endif
	/* Only one shall open for writing */

	if ((CFLASH.open_cnt && (file->f_flags & O_EXCL)) ||
		(CFLASH.open_mode & O_EXCL) ||
		((file->f_mode & 2) && (CFLASH.open_mode & O_RDWR)))
		return -EBUSY;

	if (file->f_flags & O_EXCL)
		CFLASH.open_mode |= O_EXCL;

	if (file->f_mode & 2)
		CFLASH.open_mode |= O_RDWR;

	CFLASH.open_cnt++;

	
#ifdef MODULE
	inc_mod();
#endif
	return 0;
}

static int bios_release(struct inode *inode, struct file *file)
{
	currflash=FDEV;
	if (file->f_flags & O_EXCL)
		CFLASH.open_mode &= ~O_EXCL;

	if (file->f_mode & 2)
		CFLASH.open_mode &= ~O_RDWR;

	CFLASH.open_cnt--;
	
#ifdef MODULE
	dec_mod();
#endif
	return 0;
}

struct file_operations bios_fops = {
        .owner		= THIS_MODULE,
	.llseek		= bios_llseek,
	.read		= bios_read,
	.write		= bios_write,
	.open		= bios_open,
	.release	= bios_release,
};

