patch-2.4.17 linux/drivers/char/mem.c
Next file: linux/drivers/char/pcmcia/serial_cs.c
Previous file: linux/drivers/char/joystick/pcigame.c
Back to the patch index
Back to the overall index
- Lines: 61
- Date:
Fri Dec 21 16:40:32 2001
- Orig file:
linux-2.4.16/drivers/char/mem.c
- Orig date:
Fri Sep 14 21:04:07 2001
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.16/drivers/char/mem.c linux/drivers/char/mem.c
@@ -272,6 +272,8 @@
return virtr + read;
}
+extern long vwrite(char *buf, char *addr, unsigned long count);
+
/*
* This function writes to the *virtual* memory as seen by the kernel.
*/
@@ -279,12 +281,46 @@
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
+ ssize_t wrote = 0;
+ ssize_t virtr = 0;
+ char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
+
+ if (p < (unsigned long) high_memory) {
+ wrote = count;
+ if (count > (unsigned long) high_memory - p)
+ wrote = (unsigned long) high_memory - p;
+
+ wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
+
+ p += wrote;
+ buf += wrote;
+ count -= wrote;
+ }
+
+ if (count > 0) {
+ kbuf = (char *)__get_free_page(GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+ while (count > 0) {
+ int len = count;
+
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+ if (len && copy_from_user(kbuf, buf, len)) {
+ free_page((unsigned long)kbuf);
+ return -EFAULT;
+ }
+ len = vwrite(kbuf, (char *)p, len);
+ count -= len;
+ buf += len;
+ virtr += len;
+ p += len;
+ }
+ free_page((unsigned long)kbuf);
+ }
- if (p >= (unsigned long) high_memory)
- return 0;
- if (count > (unsigned long) high_memory - p)
- count = (unsigned long) high_memory - p;
- return do_write_mem(file, (void*)p, p, buf, count, ppos);
+ *ppos = p;
+ return virtr + wrote;
}
#if !defined(__mc68000__)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)