Annotation of qemu/roms/openbios/utils/devbios/filesystem.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *                     OpenBIOS - free your system! 
        !             3:  *              ( firmware/flash device driver for Linux )
        !             4:  *                          
        !             5:  *  filesystem.c - vfs character device interface
        !             6:  *  
        !             7:  *  This program is part of a free implementation of the IEEE 1275-1994 
        !             8:  *  Standard for Boot (Initialization Configuration) Firmware.
        !             9:  *
        !            10:  *  Copyright (C) 1998-2004  Stefan Reinauer, <[email protected]>
        !            11:  *
        !            12:  *  This program is free software; you can redistribute it and/or modify
        !            13:  *  it under the terms of the GNU General Public License as published by
        !            14:  *  the Free Software Foundation; version 2 of the License.
        !            15:  *
        !            16:  *  This program is distributed in the hope that it will be useful,
        !            17:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            18:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            19:  *  GNU General Public License for more details.
        !            20:  *
        !            21:  *  You should have received a copy of the GNU General Public License
        !            22:  *  along with this program; if not, write to the Free Software
        !            23:  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
        !            24:  *
        !            25:  */
        !            26: 
        !            27: #include <linux/config.h>
        !            28: #include <linux/version.h>
        !            29: #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) && defined(MODVERSIONS)
        !            30: #include <linux/modversions.h>
        !            31: #endif
        !            32: #include <linux/module.h>
        !            33: #include <linux/errno.h>
        !            34: #include <linux/types.h>
        !            35: #include <linux/vmalloc.h>
        !            36: #include <linux/fcntl.h>
        !            37: #include <linux/delay.h>
        !            38: 
        !            39: #include <asm/uaccess.h>
        !            40: 
        !            41: #include "bios.h"
        !            42: #include "flashchips.h"
        !            43: #include "pcisets.h"
        !            44: #include "programming.h"
        !            45: 
        !            46: #ifdef MODULE
        !            47: void inc_mod(void);
        !            48: void dec_mod(void);
        !            49: #endif
        !            50: 
        !            51: /*
        !            52:  * ******************************************
        !            53:  *
        !            54:  *     /dev/bios filesystem operations
        !            55:  *
        !            56:  * ****************************************** 
        !            57:  */
        !            58: 
        !            59: #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
        !            60: #define FDEV           (MINOR(file->f_dentry->d_inode->i_rdev))
        !            61: #else
        !            62: #define FDEV           (iminor(file->f_dentry->d_inode))
        !            63: #endif
        !            64: #define CFLASH         flashdevices[FDEV]
        !            65: // #define BIOS_SIZE   ((flashchips[CFLASH.flashnum].size)*1024)
        !            66: #define BIOS_SIZE      (CFLASH.size)
        !            67: 
        !            68: static loff_t bios_llseek(struct file *file, loff_t offset, int origin )
        !            69: {
        !            70:        currflash=FDEV;
        !            71:        switch(origin) {
        !            72:          case 0:
        !            73:                break;
        !            74:          case 1:
        !            75:                offset += file->f_pos;
        !            76:                break;
        !            77:          case 2:
        !            78:                offset += BIOS_SIZE;
        !            79:                break;
        !            80:        }
        !            81:        return((offset >= 0)?(file->f_pos = offset):-EINVAL);
        !            82: }
        !            83: 
        !            84: static ssize_t bios_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
        !            85: {
        !            86:        signed int size=((BIOS_SIZE-*ppos>count) ? count : BIOS_SIZE-*ppos);
        !            87:        unsigned char *addr = (unsigned char*)CFLASH.mapped + CFLASH.offset;
        !            88:        int i;
        !            89: 
        !            90:        currflash = FDEV;
        !            91: 
        !            92:        devices[flashdevices[currflash].idx].activate();
        !            93: 
        !            94:        for (i=0;i<size;i++) 
        !            95:                buffer[i]=flash_readb(addr,*ppos+i);
        !            96: 
        !            97:        devices[flashdevices[currflash].idx].deactivate();
        !            98: 
        !            99:        *ppos+=size;
        !           100:        return size;
        !           101: }
        !           102: 
        !           103: static ssize_t bios_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
        !           104: {
        !           105:         unsigned long flags;
        !           106:        unsigned int offset=0, startsec=0, endsec=0;
        !           107:        unsigned int secnum=0, size=0, writeoffs=0;
        !           108:        unsigned int i, fn;
        !           109:        unsigned char *clipboard;
        !           110:        unsigned char *addr = (unsigned char*)CFLASH.mapped + CFLASH.offset;
        !           111: 
        !           112:        currflash=FDEV;
        !           113:        fn=CFLASH.flashnum;
        !           114: 
        !           115:        /* Some security checks. */
        !           116: 
        !           117: #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
        !           118:        if (!suser())
        !           119:                return -EACCES;
        !           120: #endif
        !           121: 
        !           122:        if (!write) {
        !           123:                printk (KERN_WARNING "Writing is disabled for security reasons.  RTFM.\n");
        !           124:                return -EACCES;
        !           125:        }
        !           126: 
        !           127:        if (!flashchips[fn].supported) {
        !           128:                printk (KERN_ERR "BIOS: Flash device not supported.\n");
        !           129:                return -EMEDIUMTYPE;
        !           130:        }
        !           131: 
        !           132:        if ( count > BIOS_SIZE-*ppos )
        !           133:                return -EFBIG;
        !           134: 
        !           135:        /* FIXME: Autoselect(AMD) BC-90 
        !           136:         * -> 00/MID; 
        !           137:         *    01/PID; 
        !           138:         *    02/Protected (1=yes/0=no)
        !           139:         */
        !           140: 
        !           141:        /* Determine size of data to be written */
        !           142: 
        !           143:        if (!(flashchips[fn].flags & f_needs_erase) ) {
        !           144:                offset=(unsigned int)*ppos&~(flashchips[fn].pagesize-1);
        !           145:                size=(((unsigned int)*ppos+count+(flashchips[fn].pagesize-1))&
        !           146:                                ~(flashchips[CFLASH.flashnum].pagesize-1))-offset;
        !           147:        } else {
        !           148:                while (flashchips[fn].sectors[secnum] <= flashchips[fn].size ) {
        !           149:                        if ((unsigned int)*ppos >= flashchips[fn].sectors[secnum]*1024) {
        !           150:                                offset=flashchips[fn].sectors[secnum]*1024;
        !           151:                                startsec=secnum;
        !           152:                        }
        !           153:                        if ((unsigned int)*ppos+count-1 <= flashchips[fn].sectors[secnum]*1024) {
        !           154:                                size=(flashchips[fn].sectors[secnum]*1024)-offset;
        !           155:                                endsec=secnum-1;
        !           156:                                break;
        !           157:                        }
        !           158:                        secnum++;
        !           159:                }
        !           160:        }
        !           161: 
        !           162: #ifdef DEBUG
        !           163:        printk (KERN_DEBUG "BIOS: Write [0x%06x..0x%06x] [0x%06x..0x%06x]\n",
        !           164:                        (unsigned int)(*ppos),(unsigned int)(*ppos+count-1),offset,offset+size-1);
        !           165: #endif
        !           166: 
        !           167:        /* prepare data for writing */
        !           168: 
        !           169:        clipboard=vmalloc(size);
        !           170: 
        !           171:        spin_lock_irqsave(&bios_lock, flags);
        !           172: 
        !           173:        devices[flashdevices[currflash].idx].activate();
        !           174: 
        !           175:        for (i=0; i < size; i++) 
        !           176:                clipboard[i] = flash_readb(addr,offset+i);
        !           177: 
        !           178:        copy_from_user(clipboard+(*ppos-offset), buffer, count);
        !           179: 
        !           180:        /* start write access */
        !           181: 
        !           182:        if (flashchips[fn].flags & f_intel_compl) {
        !           183:                iflash_erase_sectors(addr,fn,startsec,endsec);
        !           184: 
        !           185:                for (i=0;i<size;i++)
        !           186:                        iflash_program_byte(addr, offset+i, clipboard[i]);
        !           187: 
        !           188:                flash_command(addr, 0xff);
        !           189: 
        !           190:        } else {
        !           191: 
        !           192:          if (flashchips[fn].flags & f_needs_erase) {
        !           193:            if (size == flashchips[fn].size*1024) { /* whole chip erase */
        !           194:              printk (KERN_DEBUG "BIOS: Erasing via whole chip method\n");
        !           195:              flash_erase(addr, fn);
        !           196:            } else {
        !           197:              printk (KERN_DEBUG "BIOS: Erasing via sector method\n");
        !           198:              flash_erase_sectors(addr, fn,startsec,endsec);
        !           199:            }
        !           200:          } 
        !           201: 
        !           202:          while (size>0) {
        !           203:            if ((flashchips[fn].flags & f_manuf_compl) != f_atmel_compl) {
        !           204:              flash_program(addr);
        !           205:            } else {
        !           206:              flash_program_atmel(addr);
        !           207:            }
        !           208:            for (i=0;i<flashchips[fn].pagesize;i++) {
        !           209:              flash_writeb(addr,offset+writeoffs+i,clipboard[writeoffs+i]);
        !           210:            }
        !           211:            if ((flashchips[fn].flags & f_manuf_compl) == f_atmel_compl) {
        !           212:              udelay(750);
        !           213:            } else {
        !           214:                    if (flashchips[fn].pagesize==1)
        !           215:                            udelay(30);
        !           216:                    else
        !           217:                            udelay(300);
        !           218:            }
        !           219: 
        !           220:            if (flash_ready_poll(addr,offset+writeoffs+flashchips[fn].pagesize-1,
        !           221:                                 clipboard[writeoffs+flashchips[fn].pagesize-1])) {
        !           222:              printk (KERN_ERR "BIOS: Error occured, please repeat write operation.\n");
        !           223:            }
        !           224:            flash_command(addr, 0xf0);
        !           225:            
        !           226:            writeoffs += flashchips[fn].pagesize;
        !           227:            size          -= flashchips[fn].pagesize;
        !           228:          }
        !           229:        }
        !           230: 
        !           231:        devices[flashdevices[currflash].idx].deactivate();
        !           232: 
        !           233:        spin_unlock_irqrestore(&bios_lock, flags);
        !           234: 
        !           235:        vfree(clipboard);
        !           236: 
        !           237:        *ppos+=count;
        !           238:        return count;
        !           239: }
        !           240: 
        !           241: static int bios_open(struct inode *inode, struct file *file)
        !           242: {
        !           243:        currflash=FDEV;
        !           244:        
        !           245:        if (flashcount<=FDEV) {
        !           246:                printk (KERN_ERR "BIOS: There is no device (%d).\n",FDEV);
        !           247:                return -ENODEV;
        !           248:        }
        !           249: 
        !           250: #ifdef DEBUG
        !           251:        printk(KERN_DEBUG "BIOS: Opening device %d\n",FDEV);
        !           252: #endif
        !           253:        /* Only one shall open for writing */
        !           254: 
        !           255:        if ((CFLASH.open_cnt && (file->f_flags & O_EXCL)) ||
        !           256:                (CFLASH.open_mode & O_EXCL) ||
        !           257:                ((file->f_mode & 2) && (CFLASH.open_mode & O_RDWR)))
        !           258:                return -EBUSY;
        !           259: 
        !           260:        if (file->f_flags & O_EXCL)
        !           261:                CFLASH.open_mode |= O_EXCL;
        !           262: 
        !           263:        if (file->f_mode & 2)
        !           264:                CFLASH.open_mode |= O_RDWR;
        !           265: 
        !           266:        CFLASH.open_cnt++;
        !           267: 
        !           268:        
        !           269: #ifdef MODULE
        !           270:        inc_mod();
        !           271: #endif
        !           272:        return 0;
        !           273: }
        !           274: 
        !           275: static int bios_release(struct inode *inode, struct file *file)
        !           276: {
        !           277:        currflash=FDEV;
        !           278:        if (file->f_flags & O_EXCL)
        !           279:                CFLASH.open_mode &= ~O_EXCL;
        !           280: 
        !           281:        if (file->f_mode & 2)
        !           282:                CFLASH.open_mode &= ~O_RDWR;
        !           283: 
        !           284:        CFLASH.open_cnt--;
        !           285:        
        !           286: #ifdef MODULE
        !           287:        dec_mod();
        !           288: #endif
        !           289:        return 0;
        !           290: }
        !           291: 
        !           292: struct file_operations bios_fops = {
        !           293:         .owner         = THIS_MODULE,
        !           294:        .llseek         = bios_llseek,
        !           295:        .read           = bios_read,
        !           296:        .write          = bios_write,
        !           297:        .open           = bios_open,
        !           298:        .release        = bios_release,
        !           299: };
        !           300: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.