From: Adrian M. <zx8...@us...> - 2002-08-28 00:02:57
|
Update of /cvsroot/linuxdc/linux-sh-dc/drivers/mtd/maps In directory usw-pr-cvs1:/tmp/cvs-serv14607/drivers/mtd/maps Modified Files: vmu-flash.c Log Message: Updated VMU Flash driver Index: vmu-flash.c =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/drivers/mtd/maps/vmu-flash.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- vmu-flash.c 24 Aug 2002 10:05:41 -0000 1.3 +++ vmu-flash.c 28 Aug 2002 00:02:53 -0000 1.4 @@ -43,6 +43,20 @@ unsigned int ofs; /* Block Offset */ } block_t; +typedef struct vmu_cache_s { + char *buffer; /* Cached memory block */ + unsigned int block; /* Which block was cached */ + unsigned long jiffies_atc; /* When was it cached */ + int valid; /* Cache currently valid? */ +} vmu_cache_t; + + +vmu_cache_t *vmu_cache = NULL; + +wait_queue_head_t wq_mq; +DECLARE_WAIT_QUEUE_HEAD(wq_mq); + + /*************************************/ /**********Read and write routines*************/ int maple_vmu_read_block(unsigned int num, u_char * buf) @@ -69,7 +83,10 @@ ((unsigned long *) (mqu->recvbuf))[0] = cpu_to_be32(MAPLE_FUNC_MEMCARD); - ((unsigned long *) (mqu->recvbuf))[1] = num; + + /* With thanks to KOS */ + ((unsigned long *) (mqu->recvbuf))[1] = + /*((num & 0xff) << 24) | ((num >> 8) << 16) */ num << 24; mqu->sendbuf = mqu->recvbuf; if (maple_add_packet(mqu) != 0) { printk(KERN_WARNING "VMU FLASH: Could not add packet\n"); @@ -77,22 +94,24 @@ } lastmq = NULL; - wait_queue_head_t wq_mq; - init_waitqueue_head(&wq_mq); + do { interruptible_sleep_on_timeout(&wq_mq, 1); } while (lastmq == NULL); /* Now check if we've got a proper return */ - if (block_buffer){ - memcpy(block_buffer, buf, 512); - kfree(block_buffer); - block_buffer = NULL; - return 0; + if (block_buffer) { + memcpy(block_buffer, buf, 512); + kfree(block_buffer); + block_buffer = NULL; + return 0; } - printk(KERN_WARNING "VMU FLASH: Read has failed\n"); + printk(KERN_WARNING + "VMU FLASH: Read has failed - return is 0x%X\n", + lastmq->recvbuf[0]); + printk(KERN_WARNING "ERROR code is 0x%X\n", lastmq->recvbuf[1]); return -1; @@ -195,6 +214,7 @@ * Reads a byte from a VMU at the specified offset. * */ + static __u8 vmu_flash_read8(unsigned long ofs, long *retval) { block_t *block; @@ -209,6 +229,27 @@ *retval = 1; return -1; } + + /* Is this cached? */ + if (vmu_cache->valid) { + if (vmu_cache->block == block->num) { + if ((vmu_cache->jiffies_atc + 10) >= jiffies) { /* short lifespan */ + memcpy(vmu_cache->buffer, buf, 512); + u_char *buf2 = buf; + buf2 += block->ofs; + + kfree(block); + __u8 ret = (__u8) * buf2; + kfree(buf); + + return ret; + } else + vmu_cache->valid = 0; /* Force a read faster */ + } + } + + + /* Read the block */ if (maple_vmu_read_block(block->num, buf) == -1) { printk(KERN_WARNING "Can't read block: %d\n", block->num); @@ -221,7 +262,7 @@ buf2 += block->ofs; kfree(block); - __u8 ret = (__u8) *buf2; + __u8 ret = (__u8) * buf2; kfree(buf); return ret; @@ -251,6 +292,7 @@ return; } + /* Read the block */ if (maple_vmu_read_block(block->num, buf)) { printk(KERN_WARNING "Can't read block: %d\n", block->num); @@ -276,38 +318,39 @@ /* Read and Write routines */ int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char * buf) + size_t * retlen, u_char * buf) { - printk("Reading from %llx with length %llx\n", from, len); + /* printk("Reading from %llx with length %llx\n", from, len); */ if (len < 1) return -1; - if (len > (128 * 1024)) len = 128 * 1024; - int start_here = (int)(from & 0xffffffff); + if (len > (128 * 1024)) + len = 128 * 1024; + int start_here = (int) (from & 0xffffffff); long retval = 0; int index = 0; do { - u8 cx = vmu_flash_read8(start_here + index, &retval ); - if (retval){ - *retlen = index; - return -1; + u8 cx = vmu_flash_read8(start_here + index, &retval); + if (retval) { + *retlen = index; + return -1; } memset(buf + index, cx, 1); index++; } while (len > index); - *retlen = index; + *retlen = index; return 0; } -int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t *retlen, size_t len, - const u_char * buf) +int vmu_flash_write(struct mtd_info *mtd, loff_t from, size_t len, + size_t * retlen, const u_char * buf) { if (len < 1) return -1; int index = 0; do { - vmu_flash_write8(buf[index], to + index); + vmu_flash_write8(buf[index], from + index); index++; } while (len > index); *retlen = index; @@ -316,9 +359,9 @@ int vmu_flash_erase(struct mtd_info *mtd, struct erase_info *erase) { - int *z = (int *)kmalloc(4, GFP_KERNEL); - vmu_flash_write(mtd, erase->addr, erase->len, z, "\0"); - kfree(z); + int z; + vmu_flash_write(mtd, erase->addr, erase->len, &z, "\0"); + return 0; } @@ -377,16 +420,31 @@ struct mapleq *mq = &data->mq; if (mq->recvbuf[0] == 8) { + /* int res = mq->recvbuf[0]; + + printk + ("Maple reply (%d, %d) cmd=%d => %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", + mq->port, mq->unit, mq->command, res, mq->recvbuf[1], + mq->recvbuf[2], mq->recvbuf[3], mq->recvbuf[4], + mq->recvbuf[5], mq->recvbuf[6], mq->recvbuf[7], + mq->recvbuf[8], mq->recvbuf[9], mq->recvbuf[10], + mq->recvbuf[11]); + */ block_buffer = kmalloc(512, GFP_KERNEL); - /* How big a transfer is it? */ - memcpy(mq->recvbuf + 12, block_buffer, - (__u8)(mq->recvbuf[3]) * 2 - 8); - + /* Copy over */ + memcpy(mq->recvbuf + 12, block_buffer, 512); lastmq = mq; + wake_up_interruptible(&wq_mq); /* Wake sleeping code */ + memcpy(block_buffer, vmu_cache->buffer, 512); + vmu_cache->block = mq->recvbuf[11] & 0xff; + vmu_cache->jiffies_atc = jiffies; /* Mark the creation time */ + vmu_cache->valid = 1; /* Block is now valid */ return; - } + } lastmq = mq; + + } @@ -428,6 +486,12 @@ "VMU Flash driver initialisation failed\n"); return -1; } + + /* Create the cache */ + vmu_cache = kmalloc(64, GFP_KERNEL); + vmu_cache->buffer = kmalloc(512, GFP_KERNEL); + vmu_cache->valid = 0; + return 0; } @@ -449,6 +513,11 @@ kfree(vmu_flash_mtd); vmu_flash_mtd = NULL; } + + /* Clear the cache */ + kfree(vmu_cache->buffer); + vmu_cache->valid = 0; + kfree(vmu_cache); } |