diff options
author | Michael Lauer <mickey@vanille-media.de> | 2006-05-11 17:23:44 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2006-05-11 17:23:44 +0000 |
commit | 844bf825c75c21864c1ba911642d58021e08e9ed (patch) | |
tree | a4fc24b7330cd955c23787749f4cf751bf35dc57 /packages/linux/linux-ezx/ezx_roflash.patch | |
parent | 2222e629a6bf3ebaafce55cfd533486ec9926887 (diff) |
add first stab at support for the Motorola A780 GSM phone
NOTE: for now, we use a dedicated linux-ezx kernel, but once this proves working,
we will probably unify with linux-openzaurus
Diffstat (limited to 'packages/linux/linux-ezx/ezx_roflash.patch')
-rw-r--r-- | packages/linux/linux-ezx/ezx_roflash.patch | 895 |
1 files changed, 895 insertions, 0 deletions
diff --git a/packages/linux/linux-ezx/ezx_roflash.patch b/packages/linux/linux-ezx/ezx_roflash.patch new file mode 100644 index 0000000000..73c62b9cea --- /dev/null +++ b/packages/linux/linux-ezx/ezx_roflash.patch @@ -0,0 +1,895 @@ +Roflash driver (don't think it will be needed for 2.6.x) + +diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/block/Kconfig linux-2.6.16.5-exz/drivers/block/Kconfig +--- linux-2.6.16.5/drivers/block/Kconfig 2006-04-12 22:27:57.000000000 +0200 ++++ linux-2.6.16.5-exz/drivers/block/Kconfig 2006-04-16 18:49:29.000000000 +0200 +@@ -453,4 +453,6 @@ + This driver provides Support for ATA over Ethernet block + devices like the Coraid EtherDrive (R) Storage Blade. + ++source "drivers/block/roflash/Kconfig" ++ + endmenu +diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/block/Makefile linux-2.6.16.5-exz/drivers/block/Makefile +--- linux-2.6.16.5/drivers/block/Makefile 2006-04-12 22:27:57.000000000 +0200 ++++ linux-2.6.16.5-exz/drivers/block/Makefile 2006-04-16 18:49:29.000000000 +0200 +@@ -31,3 +31,4 @@ + obj-$(CONFIG_BLK_DEV_SX8) += sx8.o + obj-$(CONFIG_BLK_DEV_UB) += ub.o + ++obj-$(CONFIG_ARCH_EZX_ROFLASH) += roflash/ +diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/block/roflash/Kconfig linux-2.6.16.5-exz/drivers/block/roflash/Kconfig +--- linux-2.6.16.5/drivers/block/roflash/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.5-exz/drivers/block/roflash/Kconfig 2006-04-16 18:49:29.000000000 +0200 +@@ -0,0 +1,7 @@ ++# ++# Emualting Flash Chip driver configuration ++# ++config ARCH_EZX_ROFLASH ++ tristate 'ROFLASH Device' ++ ++#tristate 'Debug for ROFLASH device?' ROFLASH_DEBUG_ERR +diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/block/roflash/Makefile linux-2.6.16.5-exz/drivers/block/roflash/Makefile +--- linux-2.6.16.5/drivers/block/roflash/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.5-exz/drivers/block/roflash/Makefile 2006-04-16 18:49:29.000000000 +0200 +@@ -0,0 +1,15 @@ ++# ++# Makefile for VFM ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++# Note 2! The CFLAGS definitions are now inherited from the ++# parent makes.. ++ ++# ++# Makefile for the kernel VSB driver. ++# ++ ++obj-$(CONFIG_ARCH_EZX_ROFLASH) += roflash.o ezx_parts.o +diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/block/roflash/ezx_parts.c linux-2.6.16.5-exz/drivers/block/roflash/ezx_parts.c +--- linux-2.6.16.5/drivers/block/roflash/ezx_parts.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.5-exz/drivers/block/roflash/ezx_parts.c 2006-04-16 18:49:29.000000000 +0200 +@@ -0,0 +1,198 @@ ++/* ++ * drivers/mtd/maps/ezx_parts.c ++ * ++ * Parse multiple flash partitions in Ezx project into mtd_table or into act_roflash_table ++ * ++ * Created by Susan Gu Oct, 22 2002 ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/types.h> ++#include <linux/kernel.h> ++#include <asm/io.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/map.h> ++#include <linux/mtd/partitions.h> ++#include <linux/ezx_roflash.h> ++ ++extern int roflash_init(void); ++ ++extern int cfi_intelext_read_roflash(void *priv_map, unsigned long from, size_t len, size_t *retlen, u_char *buf); ++extern int cfi_intelext_read_roflash_c(void *priv_map, unsigned long from, size_t len, size_t *retlen, u_char *buf); ++roflash_area **roflash_table_pptr = NULL; ++ ++static DECLARE_MUTEX(roflash_table_mutex); ++ ++/* I know what I am doing, so setup l_x_b flag */ ++#ifdef CONFIG_ARCH_EZX_A780 ++static roflash_area fix_roflash_table[]= ++{ ++ { ++ name: "rootfs", ++ size: 0x018E0000, /* rootfs size is 24.875MB */ ++ offset: 0x00120000, ++ roflash_read: NULL, /* force read-only in cacheable mapping*/ ++ l_x_b: ROFLASH_LINEAR, ++ phys_addr: 0x00000000, ++ },{ ++ name: "NO-USE", /* language package is moved to MDOC */ ++ size: 0x00000000, ++ offset: 0x01A00000, //Susan -- correspond to the beginning of the second flash chip // ++ roflash_read: cfi_intelext_read_roflash, ++ l_x_b: ROFLASH_BLOCK, ++ phys_addr: 0xffffffff, // not use for block cramfs mount ++ },{ ++ name: "setup", ++ size: 0x00020000, ++ offset: 0x01FA0000, ++ roflash_read: cfi_intelext_read_roflash, ++ l_x_b: ROFLASH_BLOCK, ++ phys_addr: 0xffffffff, // not use for block cramfs mount ++ } ++}; ++#if (0) ++static roflash_area fix_roflash_table[]= ++{ ++ { ++ name: "rootfs", ++ size: 0x00f00000, /* rootfs size is 15MB */ ++ offset: 0x00100000, ++ roflash_read: NULL, /* force read-only in cacheable mapping*/ ++ l_x_b: ROFLASH_LINEAR_XIP, ++ phys_addr: 0x00000000, ++ },{ ++ name: "nxipapp", /* old language area is 0xAA0000 */ ++ size: 0x00AA0000, ++ offset: 0x00500000, ++ roflash_read: cfi_intelext_read_roflash, ++ l_x_b: ROFLASH_BLOCK, ++ phys_addr: 0xffffffff, // not use for block cramfs mount ++ },{ ++ name: "setup", /* setup stuff is 1MB */ ++ size: 0x00020000, ++ offset: 0x00FA0000, ++ roflash_read: cfi_intelext_read_roflash, ++ l_x_b: ROFLASH_BLOCK, ++ phys_addr: 0xffffffff, //phys_addr is not useful for block cramfs mount ++ } ++}; ++#endif ++ ++#endif ++ ++#ifdef CONFIG_ARCH_EZX_E680 ++static roflash_area fix_roflash_table[]= ++{ ++ { ++ name: "rootfs", ++ size: 0x018E0000, /* rootfs size is 15MB */ ++ offset: 0x00120000, ++ roflash_read: NULL, /* force read-only in cacheable mapping*/ ++ l_x_b: ROFLASH_LINEAR, ++ phys_addr: 0x00000000, ++ },{ ++ name: "NO-USE", /* language package is 2MB */ ++ size: 0x00000000, ++ offset: 0x01A00000, //Susan -- correspond to the beginning of the second flash chip // ++ roflash_read: cfi_intelext_read_roflash, ++ l_x_b: ROFLASH_BLOCK, ++ phys_addr: 0xffffffff, // not use for block cramfs mount ++ },{ ++ name: "setup", /* setup stuff is 1MB */ ++ size: 0x00020000, ++ offset: 0x01FA0000, //Susan -- correspond to the beginning of the second flash chip // ++ roflash_read: cfi_intelext_read_roflash, ++ l_x_b: ROFLASH_BLOCK, ++ phys_addr: 0xffffffff, // not use for block cramfs mount ++ } ++}; ++#endif ++ ++roflash_area *act_roflash_table[MAX_ROFLASH] = {0}; ++unsigned short roflash_partitions = 0; ++ ++/* If we decide to use flash partition parse table, this function will parse the fpt - flash partition table, ++* the beginning address of fpt is defined in CONFIG_FPT_OFFSET. This function will parser out all roflash areas ++* and animation area( or re-fresh code area). ++* For roflash areas, registered them into act_roflash_table, for animation region, register it into mtd_table[6]. ++* Note ++* 6 is fixed for animation region -- /dev/mtd6 c 90 12 ++* /dev/roflash b 62 0 -- root file system ++* /dev/roflash1 b 62 1 -- language package ++* /dev/roflash2 b 62 2 -- setup stuff ++*/ ++int ezx_parse(struct map_info *chip_map) ++{ ++ return 0; // depends on discussion about DC tool ++} ++ ++int ezx_parts_parser(void) ++{ ++ int ret = 0; ++ int nrparts = 0; ++ int i = 0; ++ ++//#ifdef CONFIG_EZX_PARSER_TABLE ++// ret = ezx_parse(chip_map); ++//#else ++ down(&roflash_table_mutex); ++ ++ nrparts = sizeof(fix_roflash_table) / sizeof(roflash_area); ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk("ezx_parts_parser: nrparts is %d\n", nrparts); ++#endif ++ for ( i = 0; i < nrparts; i ++ ) ++ { ++ if (act_roflash_table[i]) ++ return -1; ++ act_roflash_table[i] = (roflash_area *)(&(fix_roflash_table[i])); ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "ezx_parts_parser: act_roflash_table[%d] = %d\n",i,(unsigned long)(act_roflash_table[i])); ++#endif ++ } ++ roflash_partitions = i; ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk("ezx_parts_parser: roflash_partitions is %d\n", roflash_partitions); ++#endif ++ ++ up(&roflash_table_mutex); ++ ++ return ret; ++} ++ ++int ezx_partition_init(void) ++{ ++ int ret = 0; ++ ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "ezx_partition_init: roflash_table_pptr = %d\n",(unsigned long)(act_roflash_table)); ++#endif ++ roflash_table_pptr = (roflash_area **)(act_roflash_table); ++ ++ if ( ret = ezx_parts_parser() ) ++ { ++ printk(KERN_NOTICE "invoke ezx_parts_parser, return %d\n", ret); ++ return -EIO; ++ } ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk("ezx_partition_init: ret of ezx_parts_parser is %d\n", ret); ++#endif ++ ++ if ( ret = roflash_init() ) ++ { ++ printk(KERN_NOTICE "invoke roflash_init, return %d\n", ret); ++ return -EIO; ++ } ++ return 0 ; ++} ++ ++ ++ ++ ++ ++ +diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/block/roflash/roflash.c linux-2.6.16.5-exz/drivers/block/roflash/roflash.c +--- linux-2.6.16.5/drivers/block/roflash/roflash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.5-exz/drivers/block/roflash/roflash.c 2006-04-16 18:49:29.000000000 +0200 +@@ -0,0 +1,593 @@ ++/* ++ * Linux Flash read-only block device driver For Cramfs file system, support simultaneous linear + block device mounting. -- Susan Gu Mar, 15 2002 ++ * In order to resolve logo area in cachable flash mapping, add roflash_c_fops methods, that is stolen from mtdchar.c (dwmw2) ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/config.h> ++#include <linux/kmod.h> ++#include <linux/types.h> ++#include <linux/init.h> ++#include <linux/vmalloc.h> ++ ++#include <asm/uaccess.h> ++#include <linux/mtd/map.h> ++#include <linux/ezx_roflash.h> ++ ++#ifdef CONFIG_PROC_FS ++#include <linux/proc_fs.h> /* For /proc/roflash_info */ ++#endif /* CONFIG_PROC_FS */ ++ ++#define MAJOR_NR ROFLASH_MAJOR ++#define DEVICE_NAME "roflash" ++#define DEVICE_REQUEST roflash_request ++#define DEVICE_NR(device) (MINOR(device)) ++#define DEVICE_ON(device) ++#define DEVICE_OFF(device) ++#define DEVICE_NO_RANDOM ++ ++#define MAJOR_NR_C 101 ++#define DEVICE_NAME_C "roflash_c" ++#include <linux/blkdev.h> ++ ++ ++/* K3 flash lowlevel */ ++#define FLASH_WORD_ALIGN_MASK 0xFFFFFFFE ++#define WIDTH_ADJUST 0x0001L /* I.E. Converts 0x90 to 0x90 */ ++#define FlashCommandRead (unsigned short)(0xFF * WIDTH_ADJUST) ++#define FlashCommandStatus (unsigned short)(0x70 * WIDTH_ADJUST) ++#define FlashStatusReady (unsigned short)(0x80 * WIDTH_ADJUST) ++ ++/* Variables used to track operational state of ROFLASH */ ++#define ROFLASH_STATUS_READY 0 ++#define ROFLASH_STATUS_NOT_READY -1 ++#define ROFLASH_BLOCK_SIZE (4096) ++static unsigned long flash_blocksizes[MAX_ROFLASH]; ++static unsigned long flash_sizes[MAX_ROFLASH]; ++ ++#ifdef CONFIG_PROC_FS ++static struct proc_dir_entry *roflash_proc_entry; ++static int roflash_read_procmem(char *, char **, off_t, int, int *, void *); ++#endif /* CONFIG_PROC_FS */ ++ ++ ++extern unsigned short roflash_partitions; ++extern struct map_info bulverde_map; ++extern unsigned long bulverde_map_cacheable; ++ ++static DEFINE_SPINLOCK(roflash_lock); ++static struct request_queue *xd_queue; ++ ++#define __KERNEL_SYSCALLS__ ++#include <linux/unistd.h> ++#include <asm/unaligned.h> ++ ++ ++void fmemoryCopy (void * dest, void * src, unsigned long bytes) ++{ ++ unsigned char *new_dest; ++ unsigned char *new_src; ++ new_dest = (unsigned char *)dest; ++ new_src = (unsigned char *)src; ++ /* while bytes to modify is not complete */ ++ while (bytes-- != 0) ++ { ++ /* update destination byte to equal src byte */ ++ *new_dest = *new_src; ++ new_dest++; ++ new_src++; ++ } ++} ++void memorySet (void * buff, unsigned long bytes, unsigned char value) ++{ ++ unsigned char * new_buff; ++ new_buff = (unsigned char *)buff; ++ /* while not at end of modification */ ++ while (bytes-- != 0) ++ { ++ /* set contents of buffer to value specified */ ++ *new_buff = value; ++ ++ /* increment to next byte */ ++ new_buff++; ++ } ++} ++ ++#if (0) ++unsigned short IntelSCSRead(unsigned long CardAddress, unsigned long Length, unsigned char * Buffer) ++{ ++ unsigned long volatile pointer; ++ unsigned short * volatile pointer0ed; ++ ++#ifdef VFM_DEBUG2 ++ if ( roflash_status == ROFLASH_STATUS_READY ) ++ { ++ printk("IntelSCSRead: PositionPtr(pointer, CardAddress);\n"); ++ printk("IntelSCSRead: pointer=%d, CardAddress=%d\n", (DWORD)pointer, (DWORD)CardAddress); ++ } ++#endif ++ pointer = (unsigned long)(DALHART_K3_BASE_ADDR + CardAddress); ++ ++ pointer0ed = (unsigned short *)((unsigned long)pointer & FLASH_WORD_ALIGN_MASK); ++#ifdef CONFIG_K3_DEBUG ++ printk("IntelSCSRead(): Reading %d bytes at 0x%lx\n",Length, pointer); ++#endif ++ ++ *pointer0ed = FlashCommandRead; /* Ensure it is in read mode */ ++ ++ /* This is assumimg that farmemory copy performs at a byte at a time */ ++ fmemoryCopy(Buffer, pointer, Length); ++ ++ return(0); ++} ++#endif ++ ++void roflash_request(request_queue_t *q) ++{ ++ unsigned short minor; ++ unsigned long offset, len, retlen; ++ unsigned short err = 0; ++ unsigned char *tmpBufPtr; ++ unsigned short nrSectors; ++ struct request *req; ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "Roflash_request(): Entered\n"); ++#endif ++ ++ while ((req = elv_next_request(q)) != NULL) { ++ unsigned block = req->sector; ++ unsigned count = req->nr_sectors; ++ struct gendisk *disk = req->rq_disk; ++ int rw = rq_data_dir(req); ++ ++ if (!(req->flags & REQ_CMD)) { ++ end_request(req, 0); ++ continue; ++ } ++ ++ if (rw != READ) { ++ printk(KERN_ERR "roflash_request(): WARNING! Unknown Request\n"); ++ end_request(req, 0); ++ } ++ ++ /* Verify minor number is in range */ ++ minor = MINOR(req->rq_dev); ++ if (minor >= roflash_partitions) ++ { ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_request(): ERROR! Out of partition range (minor = %d)\n", minor ); ++#endif ++ end_request(req, 0); ++ continue; ++ } ++ ++ /* Check if writting-request is demanded */ ++ if ( req->cmd == WRITE ) ++ { ++ printk(KERN_ERR "roflash_request: write-accessing is not allowed!\n"); ++ end_request(req, 0); ++ break; ++ } ++ ++ /* Verify sector is in range */ ++ offset = req->sector << 9; // 512 bytes per sector ++ len = req->nr_sectors << 9; // 512 bytes per sector ++ if ((offset + len) > (flash_sizes[minor] << BLOCK_SIZE_BITS)) ++ { ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_request(): ERROR! Access beyond end of partition\n" ); ++#endif ++ end_request(req, 0); ++ continue; ++ } ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_request(): minor=%d, %d sectors at sector %ld\n", minor, req->nr_sectors, req->sector); ++#endif ++ ++ /* Prepare to move data to/from the Linux buffer */ ++ nrSectors = req->nr_sectors; ++ tmpBufPtr = req->buffer; ++// blockTempBufPtr = roflashTempBuffer; -- this may cause race-condition in multiple cramfs ++ ++ roflash_area *this_area = NULL; ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_request: READ\n"); ++#endif ++// memorySet(roflashTempBuffer, len, 0x00); -- don't use the internal buffer, may exist race-conditions. ++ ++ this_area = (roflash_area *)(roflash_table_pptr[minor]); ++ err = (*this_area->roflash_read)((void *)(this_area->priv_map),(offset + this_area->offset), len, &retlen, tmpBufPtr); ++ if (err == 0) { ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR " < %x %x %x %x ...>\n",req->buffer[0],req->buffer[1],req->buffer[2],req->buffer[3]); ++#endif ++ end_request(req, 1); ++ } else { ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_request(): ERROR READ %d sectors at sector %d\n", req->nr_sectors, req->sector); ++#endif ++ end_request(req, 0); ++ } ++ } ++} ++ ++static int roflash_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++// What is the requirements? -- todo list ++ return 0; ++} ++ ++ ++static int roflash_open(struct inode * inode, struct file * filp) ++{ ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_open() called, minor = %d\n", DEVICE_NR(inode->i_rdev)); ++#endif ++ if (DEVICE_NR(inode->i_rdev) >= roflash_partitions) ++ { ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "vfm_open() Failed!\n"); ++#endif ++ return -ENXIO; ++ } ++ return 0; ++} ++ ++static int roflash_release(struct inode * inode, struct file * filp) ++{ ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_release() called\n"); ++#endif ++ return 0; ++} ++ ++ ++/*Susan 2.4.6 */ ++static struct block_device_operations roflash_fops = { ++ open: roflash_open, ++ release: roflash_release, ++ ioctl: roflash_ioctl, ++}; ++ ++static loff_t roflash_c_lseek (struct file *file, loff_t offset, int orig) ++{ ++ roflash_area *dev_def = (roflash_area *)(file->private_data); ++ ++ switch (orig) { ++ case 0: ++ /* SEEK_SET */ ++ file->f_pos = offset; ++ break; ++ case 1: ++ /* SEEK_CUR */ ++ file->f_pos += offset; ++ break; ++ case 2: ++ /* SEEK_END */ ++ file->f_pos = (unsigned long)(dev_def->size + offset); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (file->f_pos < 0) ++ file->f_pos = 0; ++ else if (file->f_pos >= dev_def->size) ++ file->f_pos = dev_def->size - 1; ++ ++ return file->f_pos; ++} ++ ++static int roflash_c_open(struct inode *inode, struct file *file) ++{ ++ int minor = MINOR(inode->i_rdev); ++ roflash_area *dev_def; ++ ++ if (minor >= MAX_ROFLASH) ++ return -EACCES; ++ ++ dev_def = (roflash_area *)(roflash_table_pptr[minor]); ++ ++ /* Sanity check */ ++ if (dev_def->l_x_b != ROFLASH_CHAR) ++ return -EACCES; ++ ++ /* You can't open the RO devices RW */ ++ if (file->f_mode & 2) ++ return -EACCES; ++ ++ file->private_data = dev_def; ++ ++ return 0; ++} /* mtd_open */ ++ ++static int roflash_c_close(struct inode *inode, struct file *file) ++{ ++ return 0; ++} /* mtd_close */ ++ ++/* FIXME: This _really_ needs to die. In 2.5, we should lock the ++ userspace buffer down and use it directly with readv/writev. ++*/ ++#define MAX_KMALLOC_SIZE 0x20000 ++ ++static int roflash_c_read(struct file *file, char *buf, size_t count,loff_t *ppos) ++{ ++ roflash_area *dev_def = (roflash_area *)file->private_data; ++ size_t retlen=0; ++ size_t total_retlen=0; ++ int ret=0; ++ int len; ++ char *kbuf; ++ unsigned long virt_dev_start = 0; ++ ++ if (*ppos + count > dev_def->size) ++ count = dev_def->size - *ppos; ++ ++ if (!count) ++ return 0; ++ ++ /* FIXME: Use kiovec in 2.5 to lock down the user's buffers ++ and pass them directly to the MTD functions */ ++ while (count) ++ { ++ if (count > MAX_KMALLOC_SIZE) ++ len = MAX_KMALLOC_SIZE; ++ else ++ len = count; ++ ++ kbuf=kmalloc(len,GFP_KERNEL); ++ if (!kbuf) ++ return -ENOMEM; ++ ++ //ret = (dev_def->roflash_read)( (void *)(dev_def->priv_map),(*ppos + dev_def->offset), len, &retlen, kbuf); ++ virt_dev_start = (unsigned long)(dev_def->priv_map) + dev_def->offset; ++ memcpy(kbuf,virt_dev_start + *ppos,len); ++ ++ *ppos += len; ++ if (copy_to_user(buf, kbuf, len)) ++ { ++ kfree(kbuf); ++ return -EFAULT; ++ } ++ else ++ total_retlen += len; ++ ++ count -= len; ++ buf += len; ++ ++ ++ kfree(kbuf); ++ } ++ ++ return total_retlen; ++} /* mtd_read */ ++ ++ ++static struct file_operations roflash_c_fops = { ++ owner: THIS_MODULE, ++ llseek: roflash_c_lseek, /* lseek */ ++ read: roflash_c_read, /* read */ ++ open: roflash_c_open, /* open */ ++ release: roflash_c_close, /* release */ ++}; ++ ++roflash_area *roflash_get_dev(unsigned char minor) ++{ ++ roflash_area *ret = NULL; ++ ++ if (minor < MAX_ROFLASH) ++ ret = (roflash_area *)(roflash_table_pptr[minor]); ++ ++ return ret; ++} ++ ++int __init roflash_init(void) ++{ ++ int i, size = 0; ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init(): Enter into this API.\n"); ++#endif ++ ++/* We should do initialization for flash chips, however, we don't need to do it ++ * twice after __init_lubbock has initialized K3 flash device */ ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init: Registering device major %d [%s]\n",ROFLASH_MAJOR,DEVICE_NAME); ++#endif ++ ++ if (register_blkdev(ROFLASH_MAJOR, DEVICE_NAME)) { ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init(): Could not get major %d", ROFLASH_MAJOR); ++#endif ++ return -EIO; ++ } ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init(): register_blkdev success\n"); ++#endif ++ ++ roflash_queue = blk_init_queue(&roflash_request, &roflash_lock); ++ if (!roflash_queue) ++ return -ENOMEM; ++ ++ struct gendisk *disk = alloc_disk(64); ++ if (!disk) ++ return -ENOMEM; ++ ++ disk->major = ROFLASH_MAJOR; ++ disk->first_minor = 0; ++ sprintf(disk->disk_name, "roflash0"); ++ sprintf(disk->devfs_name, "roflash/target0"); ++ disk->fops = &roflash_fops; ++ disk->queue = roflash_queue; ++ // set_capacity(disk, ); ++ ++ add_disk(disk); ++ ++ ++ /* We know this is invoked only once during kernel booting up, so there ++ * is not race-conditions */ ++ for (i = 0; i < roflash_partitions; i++) { ++ unsigned short lxb_flag = ((roflash_area *)(roflash_table_pptr[i]))->l_x_b; ++ ++ switch (lxb_flag) { ++ case ROFLASH_LINEAR: ++ case ROFLASH_LINEAR_XIP: ++ flash_blocksizes[i] = ROFLASH_BLOCK_SIZE; ++ size = ((roflash_area *)(roflash_table_pptr[i]))->size; ++ flash_sizes[i] = size >> BLOCK_SIZE_BITS ; ++ // The virtual address of the cacheable mapping // ++ ((roflash_area *)(roflash_table_pptr[i]))->priv_map = ++ (void *)(bulverde_map_cacheable); ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init(): not-char " ++ "roflash_table_pptr[%d]->size = %d\n",i,size); ++#endif ++ break; ++ case ROFLASH_BLOCK: ++ if (bulverde_map.size == 0) { ++ unregister_blkdev(ROFLASH_MAJOR, DEVICE_NAME); ++ return -EACCES; ++ } ++ ++ flash_blocksizes[i] = ROFLASH_BLOCK_SIZE; ++ size = ((roflash_area *)(roflash_table_pptr[i]))->size; ++ flash_sizes[i] = size >> BLOCK_SIZE_BITS ; ++ //The pointer to struct map_info of the noncacheable mapping // ++ ((roflash_area *)(roflash_table_pptr[i]))->priv_map = ++ (void *)(&bulverde_map); ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init(): not-char roflash_table_pptr[%d]->size = %d\n",i,size); ++#endif ++ break; ++ case ROFLASH_CHAR: ++ if (register_chrdev(MAJOR_NR_C, DEVICE_NAME_C, &roflash_c_fops)) { ++ printk(KERN_NOTICE "Can't allocate major number %d for " ++ "Memory Technology Devices.\n", MAJOR_NR_C); ++ ++ unregister_blkdev(ROFLASH_MAJOR, DEVICE_NAME); ++ return -EAGAIN; ++ } ++ //The virtual address of the cacheable mapping // ++ ((roflash_area *)(roflash_table_pptr[i]))->priv_map = ++ (void *)(bulverde_map_cacheable); ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init(): char roflash_table_pptr[%d]->size " ++ "= %d\n",i,size); ++#endif ++ break; ++ } ++ } ++ ++ blksize_size[ROFLASH_MAJOR] = flash_blocksizes; ++ blk_size[ROFLASH_MAJOR] = flash_sizes; ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init(): fill in blksize_size[] and blk_size[] " ++ "success\n"); ++#endif ++ //blk_init_queue(BLK_DEFAULT_QUEUE(ROFLASH_MAJOR),&roflash_request); ++ roflash_queue = blk_init_queue(&roflash_request, &roflash_lock); ++ if (!roflash_queue) ++ return -ENOMEM; ++ ++#ifdef ROFLASH_DEBUG_ERR ++ printk(KERN_ERR "roflash_init(): ROFLASH Block device: blksize_size = %d" ++ ", blk_size = %d\n",flash_blocksizes[0],flash_sizes[0]); ++#endif ++ ++#ifdef CONFIG_PROC_FS ++ /* register procfs device */ ++ if (roflash_proc_entry = create_proc_entry("roflash_info", 0, 0)) { ++ roflash_proc_entry->read_proc = roflash_read_procmem; ++ } ++ ++#endif /* CONFIG_PROC_FS */ ++ ++ for ( i = 0; i < roflash_partitions; i ++ ) { ++ printk(KERN_NOTICE "ROFLASH Driver initialized and ready for use." ++ "Size: %d Offset: %d\n", ++ ((roflash_area*)(roflash_table_pptr[i]))->size, ++ ((roflash_area*)(roflash_table_pptr[i]))->offset); ++ } ++ ++ return (0); ++} ++ ++ ++#ifdef CONFIG_PROC_FS ++static int roflash_read_procmem(char *buf, char **start, off_t offset, int len, ++ int *eof, void *data) ++{ ++ #define LIMIT (PAGE_SIZE-80) /* don't print anymore after this size */ ++ ++ int i; ++ ++ len=0; ++ ++#if (0) ++ switch (roflash_status) ++ { ++ case ROFLASH_STATUS_NOT_READY: ++ strcpy(roflash_status_str,"Not-ready"); ++ break; ++ case ROFLASH_STATUS_READY: ++ strcpy(roflash_status_str,"Ready"); ++ break; ++ default: ++ strcpy(roflash_status_str,"Unknown!"); ++ break; ++ } ++#endif ++ ++ len += sprintf(buf+len, "ROFLASH Driver status: %s\n\n","Ready"); ++ for ( i = 0; i < roflash_partitions; i ++ ) ++ { ++ len += sprintf(buf+len, "ROFLASH area name is %s\n",((roflash_area*)(roflash_table_pptr[i]))->name); ++ len += sprintf(buf+len, "ROFLASH area size = %d bytes\n",((roflash_area*)(roflash_table_pptr[i]))->size); ++ len += sprintf(buf+len, "ROFLASH area offset = %ld bytes\n",((roflash_area*)(roflash_table_pptr[i]))->offset); ++ len += sprintf(buf+len, "ROFLASH area l_x_b(%x)\n",((roflash_area*)(roflash_table_pptr[i]))->l_x_b); ++ } ++ return len; ++} ++#endif /* CONFIG_PROC_FS */ ++ ++#ifdef MODULE ++static void __exit roflash_cleanup(void) //Susan// ++{ ++ int i; ++ int err_info = 0; ++ ++ /* For read-only flash device, we don't need to invoke fsync_dev */ ++ ++ unregister_blkdev(ROFLASH_MAJOR, DEVICE_NAME); ++ blk_cleanup_queue(BLK_DEFAULT_QUEUE(ROFLASH_MAJOR)); ++ blk_size[ROFLASH_MAJOR] = NULL; ++ blksize_size[ROFLASH_MAJOR] = NULL; ++ ++ /* For roflash char device -- sometimes, we don't have char roflash devices */ ++ for (i = 0; i < roflash_partitions; i++) ++ { ++ unsigned short lxb_flag = ((roflash_area *)(roflash_table_pptr[i]))->l_x_b; ++ ++ if (lxb_flag == ROFLASH_CHAR) ++ { ++ unregister_chrdev(MAJOR_NR_C, DEVICE_NAME_C); ++ break; ++ } ++ } ++ ++ remove_proc_entry("roflash_info",NULL); ++ ++ printk(KERN_ERR "remove roflash_info\n"); ++ ++} ++ ++module_init(roflash_init); ++module_exit(roflash_cleanup); ++ ++#endif +diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/include/linux/ezx_roflash.h linux-2.6.16.5-exz/include/linux/ezx_roflash.h +--- linux-2.6.16.5/include/linux/ezx_roflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.5-exz/include/linux/ezx_roflash.h 2006-04-16 18:49:29.000000000 +0200 +@@ -0,0 +1,41 @@ ++/* ++ * linux/include/linux/ezx_roflash.h ++ * ++ * Created by Susan Gu 0ct, 22 2002 ++ * ++ * For multiple cramfs partitions in ezx project ++ * At repsent, there are three cramfs partitions in ezx project, they are: ++ * 1. root file system ++ * 2. Language package ++ * 3. setup package ++*/ ++ ++#ifndef EZX_ROFLASH_FS_H ++#define EZX_ROFLASH_FS_H ++ ++#include <asm/ioctl.h> ++ ++#define ROFLASH_MAJOR 62 ++ ++#define ROFLASH_LINEAR 0x0010 ++#define ROFLASH_LINEAR_XIP 0x0011 ++#define ROFLASH_BLOCK 0x1000 ++#define ROFLASH_CHAR 0x1100 ++#define MAX_ROFLASH 4 ++ ++typedef struct ++{ ++ char name[16]; /* This length should be enough for DC stuff */ ++ unsigned long offset; ++ unsigned long size; ++ int (*roflash_read)(void *, unsigned long, size_t, size_t *, u_char *); ++ /* Added by Susan for multiple Linear or block cramfs */ ++ void *priv_map; ++ unsigned long phys_addr; ++ unsigned short l_x_b; ++}roflash_area; ++ ++extern roflash_area *roflash_get_dev(unsigned char minor); ++extern roflash_area **roflash_table_pptr; ++ ++#endif + |