Lines Matching refs:dev
25 static int apply_chunk_offset(struct yaffs_dev *dev, int chunk)
27 return chunk - dev->chunk_offset;
30 static int apply_block_offset(struct yaffs_dev *dev, int block)
32 return block - dev->block_offset;
35 static void yaffs2_checkpt_init_chunk_hdr(struct yaffs_dev *dev)
40 hdr.seq = dev->checkpt_page_seq;
41 hdr.sum = dev->checkpt_sum;
42 hdr.xor = dev->checkpt_xor;
44 dev->checkpt_byte_offs = sizeof(hdr);
46 memcpy(dev->checkpt_buffer, &hdr, sizeof(hdr));
49 static int yaffs2_checkpt_check_chunk_hdr(struct yaffs_dev *dev)
53 memcpy(&hdr, dev->checkpt_buffer, sizeof(hdr));
55 dev->checkpt_byte_offs = sizeof(hdr);
58 hdr.seq == dev->checkpt_page_seq &&
59 hdr.sum == dev->checkpt_sum &&
60 hdr.xor == dev->checkpt_xor;
63 static int yaffs2_checkpt_space_ok(struct yaffs_dev *dev)
65 int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks;
73 static int yaffs_checkpt_erase(struct yaffs_dev *dev)
77 if (!dev->drv.drv_erase_fn)
81 dev->internal_start_block, dev->internal_end_block);
83 for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
84 struct yaffs_block_info *bi = yaffs_get_block_info(dev, i);
85 int offset_i = apply_block_offset(dev, i);
92 dev->n_erasures++;
94 result = dev->drv.drv_erase_fn(dev, offset_i);
97 dev->n_erased_blocks++;
98 dev->n_free_chunks +=
99 dev->param.chunks_per_block;
101 dev->drv.drv_mark_bad_fn(dev, offset_i);
107 dev->blocks_in_checkpt = 0;
112 static void yaffs2_checkpt_find_erased_block(struct yaffs_dev *dev)
115 int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks;
119 dev->n_erased_blocks, dev->param.n_reserved_blocks,
120 blocks_avail, dev->checkpt_next_block);
122 if (dev->checkpt_next_block >= 0 &&
123 dev->checkpt_next_block <= dev->internal_end_block &&
126 for (i = dev->checkpt_next_block; i <= dev->internal_end_block;
130 bi = yaffs_get_block_info(dev, i);
132 dev->checkpt_next_block = i + 1;
133 dev->checkpt_cur_block = i;
142 dev->checkpt_next_block = -1;
143 dev->checkpt_cur_block = -1;
146 static void yaffs2_checkpt_find_block(struct yaffs_dev *dev)
153 dev->blocks_in_checkpt, dev->checkpt_next_block);
155 if (dev->blocks_in_checkpt < dev->checkpt_max_blocks)
156 for (i = dev->checkpt_next_block; i <= dev->internal_end_block;
158 int chunk = i * dev->param.chunks_per_block;
162 dev->tagger.read_chunk_tags_fn(dev,
163 apply_chunk_offset(dev, chunk),
174 dev->tagger.query_block_fn(dev,
175 apply_block_offset(dev, i),
181 dev->checkpt_next_block = tags.obj_id;
182 dev->checkpt_cur_block = i;
183 dev->checkpt_block_list[dev->blocks_in_checkpt] = i;
184 dev->blocks_in_checkpt++;
192 dev->checkpt_next_block = -1;
193 dev->checkpt_cur_block = -1;
196 int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing)
200 dev->checkpt_open_write = writing;
203 if (!dev->tagger.write_chunk_tags_fn ||
204 !dev->tagger.read_chunk_tags_fn ||
205 !dev->drv.drv_erase_fn ||
206 !dev->drv.drv_mark_bad_fn)
209 if (writing && !yaffs2_checkpt_space_ok(dev))
212 if (!dev->checkpt_buffer)
213 dev->checkpt_buffer =
214 kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS);
215 if (!dev->checkpt_buffer)
218 dev->checkpt_page_seq = 0;
219 dev->checkpt_byte_count = 0;
220 dev->checkpt_sum = 0;
221 dev->checkpt_xor = 0;
222 dev->checkpt_cur_block = -1;
223 dev->checkpt_cur_chunk = -1;
224 dev->checkpt_next_block = dev->internal_start_block;
227 memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk);
228 yaffs2_checkpt_init_chunk_hdr(dev);
229 return yaffs_checkpt_erase(dev);
234 dev->checkpt_byte_offs = dev->data_bytes_per_chunk;
237 dev->blocks_in_checkpt = 0;
238 dev->checkpt_max_blocks =
239 (dev->internal_end_block - dev->internal_start_block) / 16 + 2;
240 if (!dev->checkpt_block_list)
241 dev->checkpt_block_list =
242 kmalloc(sizeof(int) * dev->checkpt_max_blocks, GFP_NOFS);
244 if (!dev->checkpt_block_list)
247 for (i = 0; i < dev->checkpt_max_blocks; i++)
248 dev->checkpt_block_list[i] = -1;
253 int yaffs2_get_checkpt_sum(struct yaffs_dev *dev, u32 * sum)
257 composite_sum = (dev->checkpt_sum << 8) | (dev->checkpt_xor & 0xff);
262 static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev)
268 if (dev->checkpt_cur_block < 0) {
269 yaffs2_checkpt_find_erased_block(dev);
270 dev->checkpt_cur_chunk = 0;
273 if (dev->checkpt_cur_block < 0)
277 tags.obj_id = dev->checkpt_next_block; /* Hint to next place to look */
278 tags.chunk_id = dev->checkpt_page_seq + 1;
280 tags.n_bytes = dev->data_bytes_per_chunk;
281 if (dev->checkpt_cur_chunk == 0) {
285 yaffs_get_block_info(dev, dev->checkpt_cur_block);
287 dev->blocks_in_checkpt++;
291 dev->checkpt_cur_block * dev->param.chunks_per_block +
292 dev->checkpt_cur_chunk;
296 chunk, dev->checkpt_cur_block, dev->checkpt_cur_chunk,
299 offset_chunk = apply_chunk_offset(dev, chunk);
301 dev->n_page_writes++;
303 dev->tagger.write_chunk_tags_fn(dev, offset_chunk,
304 dev->checkpt_buffer, &tags);
305 dev->checkpt_page_seq++;
306 dev->checkpt_cur_chunk++;
307 if (dev->checkpt_cur_chunk >= dev->param.chunks_per_block) {
308 dev->checkpt_cur_chunk = 0;
309 dev->checkpt_cur_block = -1;
311 memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk);
313 yaffs2_checkpt_init_chunk_hdr(dev);
319 int yaffs2_checkpt_wr(struct yaffs_dev *dev, const void *data, int n_bytes)
325 if (!dev->checkpt_buffer)
328 if (!dev->checkpt_open_write)
332 dev->checkpt_buffer[dev->checkpt_byte_offs] = *data_bytes;
333 dev->checkpt_sum += *data_bytes;
334 dev->checkpt_xor ^= *data_bytes;
336 dev->checkpt_byte_offs++;
339 dev->checkpt_byte_count++;
341 if (dev->checkpt_byte_offs < 0 ||
342 dev->checkpt_byte_offs >= dev->data_bytes_per_chunk)
343 ok = yaffs2_checkpt_flush_buffer(dev);
349 int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes)
357 if (!dev->checkpt_buffer)
360 if (dev->checkpt_open_write)
365 if (dev->checkpt_byte_offs < 0 ||
366 dev->checkpt_byte_offs >= dev->data_bytes_per_chunk) {
368 if (dev->checkpt_cur_block < 0) {
369 yaffs2_checkpt_find_block(dev);
370 dev->checkpt_cur_chunk = 0;
374 if (dev->checkpt_cur_block < 0)
377 chunk = dev->checkpt_cur_block *
378 dev->param.chunks_per_block +
379 dev->checkpt_cur_chunk;
381 offset_chunk = apply_chunk_offset(dev, chunk);
382 dev->n_page_reads++;
385 dev->tagger.read_chunk_tags_fn(dev,
387 dev->checkpt_buffer,
391 if (tags.chunk_id != (dev->checkpt_page_seq + 1) ||
397 if(!yaffs2_checkpt_check_chunk_hdr(dev))
400 dev->checkpt_page_seq++;
401 dev->checkpt_cur_chunk++;
403 if (dev->checkpt_cur_chunk >=
404 dev->param.chunks_per_block)
405 dev->checkpt_cur_block = -1;
409 *data_bytes = dev->checkpt_buffer[dev->checkpt_byte_offs];
410 dev->checkpt_sum += *data_bytes;
411 dev->checkpt_xor ^= *data_bytes;
412 dev->checkpt_byte_offs++;
415 dev->checkpt_byte_count++;
421 int yaffs_checkpt_close(struct yaffs_dev *dev)
425 if (dev->checkpt_open_write) {
426 if (dev->checkpt_byte_offs !=
428 yaffs2_checkpt_flush_buffer(dev);
429 } else if (dev->checkpt_block_list) {
431 i < dev->blocks_in_checkpt &&
432 dev->checkpt_block_list[i] >= 0; i++) {
433 int blk = dev->checkpt_block_list[i];
436 if (dev->internal_start_block <= blk &&
437 blk <= dev->internal_end_block)
438 bi = yaffs_get_block_info(dev, blk);
444 dev->n_free_chunks -=
445 dev->blocks_in_checkpt * dev->param.chunks_per_block;
446 dev->n_erased_blocks -= dev->blocks_in_checkpt;
449 dev->checkpt_byte_count);
451 if (dev->checkpt_buffer)
457 int yaffs2_checkpt_invalidate_stream(struct yaffs_dev *dev)
463 dev->blocks_in_checkpt);
465 return yaffs_checkpt_erase(dev);