|
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);
}
|