aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdblock.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/mtdblock.c')
-rw-r--r--drivers/mtd/mtdblock.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 400dd9c8988..e84756644fd 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,21 +1,22 @@
1/* 1/*
2 * Direct MTD block device access 2 * Direct MTD block device access
3 * 3 *
4 * $Id: mtdblock.c,v 1.66 2004/11/25 13:52:52 joern Exp $ 4 * $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $
5 * 5 *
6 * (C) 2000-2003 Nicolas Pitre <nico@cam.org> 6 * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
7 * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> 7 * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/fs.h> 11#include <linux/fs.h>
15#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/sched.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/types.h>
17#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
18#include <linux/sched.h> /* TASK_* */ 19
19#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
20#include <linux/mtd/blktrans.h> 21#include <linux/mtd/blktrans.h>
21 22
@@ -31,7 +32,7 @@ static struct mtdblk_dev {
31 32
32/* 33/*
33 * Cache stuff... 34 * Cache stuff...
34 * 35 *
35 * Since typical flash erasable sectors are much larger than what Linux's 36 * Since typical flash erasable sectors are much larger than what Linux's
36 * buffer cache can handle, we must implement read-modify-write on flash 37 * buffer cache can handle, we must implement read-modify-write on flash
37 * sectors for each block write requests. To avoid over-erasing flash sectors 38 * sectors for each block write requests. To avoid over-erasing flash sectors
@@ -45,7 +46,7 @@ static void erase_callback(struct erase_info *done)
45 wake_up(wait_q); 46 wake_up(wait_q);
46} 47}
47 48
48static int erase_write (struct mtd_info *mtd, unsigned long pos, 49static int erase_write (struct mtd_info *mtd, unsigned long pos,
49 int len, const char *buf) 50 int len, const char *buf)
50{ 51{
51 struct erase_info erase; 52 struct erase_info erase;
@@ -103,18 +104,18 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
103 return 0; 104 return 0;
104 105
105 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" " 106 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
106 "at 0x%lx, size 0x%x\n", mtd->name, 107 "at 0x%lx, size 0x%x\n", mtd->name,
107 mtdblk->cache_offset, mtdblk->cache_size); 108 mtdblk->cache_offset, mtdblk->cache_size);
108 109
109 ret = erase_write (mtd, mtdblk->cache_offset, 110 ret = erase_write (mtd, mtdblk->cache_offset,
110 mtdblk->cache_size, mtdblk->cache_data); 111 mtdblk->cache_size, mtdblk->cache_data);
111 if (ret) 112 if (ret)
112 return ret; 113 return ret;
113 114
114 /* 115 /*
115 * Here we could argubly set the cache state to STATE_CLEAN. 116 * Here we could argubly set the cache state to STATE_CLEAN.
116 * However this could lead to inconsistency since we will not 117 * However this could lead to inconsistency since we will not
117 * be notified if this content is altered on the flash by other 118 * be notified if this content is altered on the flash by other
118 * means. Let's declare it empty and leave buffering tasks to 119 * means. Let's declare it empty and leave buffering tasks to
119 * the buffer cache instead. 120 * the buffer cache instead.
120 */ 121 */
@@ -123,7 +124,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
123} 124}
124 125
125 126
126static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, 127static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
127 int len, const char *buf) 128 int len, const char *buf)
128{ 129{
129 struct mtd_info *mtd = mtdblk->mtd; 130 struct mtd_info *mtd = mtdblk->mtd;
@@ -133,7 +134,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
133 134
134 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", 135 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
135 mtd->name, pos, len); 136 mtd->name, pos, len);
136 137
137 if (!sect_size) 138 if (!sect_size)
138 return MTD_WRITE (mtd, pos, len, &retlen, buf); 139 return MTD_WRITE (mtd, pos, len, &retlen, buf);
139 140
@@ -141,11 +142,11 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
141 unsigned long sect_start = (pos/sect_size)*sect_size; 142 unsigned long sect_start = (pos/sect_size)*sect_size;
142 unsigned int offset = pos - sect_start; 143 unsigned int offset = pos - sect_start;
143 unsigned int size = sect_size - offset; 144 unsigned int size = sect_size - offset;
144 if( size > len ) 145 if( size > len )
145 size = len; 146 size = len;
146 147
147 if (size == sect_size) { 148 if (size == sect_size) {
148 /* 149 /*
149 * We are covering a whole sector. Thus there is no 150 * We are covering a whole sector. Thus there is no
150 * need to bother with the cache while it may still be 151 * need to bother with the cache while it may still be
151 * useful for other partial writes. 152 * useful for other partial writes.
@@ -159,7 +160,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
159 if (mtdblk->cache_state == STATE_DIRTY && 160 if (mtdblk->cache_state == STATE_DIRTY &&
160 mtdblk->cache_offset != sect_start) { 161 mtdblk->cache_offset != sect_start) {
161 ret = write_cached_data(mtdblk); 162 ret = write_cached_data(mtdblk);
162 if (ret) 163 if (ret)
163 return ret; 164 return ret;
164 } 165 }
165 166
@@ -192,7 +193,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
192} 193}
193 194
194 195
195static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, 196static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
196 int len, char *buf) 197 int len, char *buf)
197{ 198{
198 struct mtd_info *mtd = mtdblk->mtd; 199 struct mtd_info *mtd = mtdblk->mtd;
@@ -200,9 +201,9 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
200 size_t retlen; 201 size_t retlen;
201 int ret; 202 int ret;
202 203
203 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", 204 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
204 mtd->name, pos, len); 205 mtd->name, pos, len);
205 206
206 if (!sect_size) 207 if (!sect_size)
207 return MTD_READ (mtd, pos, len, &retlen, buf); 208 return MTD_READ (mtd, pos, len, &retlen, buf);
208 209
@@ -210,7 +211,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
210 unsigned long sect_start = (pos/sect_size)*sect_size; 211 unsigned long sect_start = (pos/sect_size)*sect_size;
211 unsigned int offset = pos - sect_start; 212 unsigned int offset = pos - sect_start;
212 unsigned int size = sect_size - offset; 213 unsigned int size = sect_size - offset;
213 if (size > len) 214 if (size > len)
214 size = len; 215 size = len;
215 216
216 /* 217 /*
@@ -268,12 +269,12 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
268 int dev = mbd->devnum; 269 int dev = mbd->devnum;
269 270
270 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); 271 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
271 272
272 if (mtdblks[dev]) { 273 if (mtdblks[dev]) {
273 mtdblks[dev]->count++; 274 mtdblks[dev]->count++;
274 return 0; 275 return 0;
275 } 276 }
276 277
277 /* OK, it's not open. Create cache info for it */ 278 /* OK, it's not open. Create cache info for it */
278 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); 279 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
279 if (!mtdblk) 280 if (!mtdblk)
@@ -292,7 +293,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
292 } 293 }
293 294
294 mtdblks[dev] = mtdblk; 295 mtdblks[dev] = mtdblk;
295 296
296 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 297 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
297 298
298 return 0; 299 return 0;
@@ -320,7 +321,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
320 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 321 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
321 322
322 return 0; 323 return 0;
323} 324}
324 325
325static int mtdblock_flush(struct mtd_blktrans_dev *dev) 326static int mtdblock_flush(struct mtd_blktrans_dev *dev)
326{ 327{