1 /*======================================================================
3 $Id: doc1000.c,v 1.15 2001/10/02 15:05:13 dwmw2 Exp $
5 ======================================================================*/
8 #include <linux/config.h>
9 #include <linux/module.h>
10 #include <asm/uaccess.h>
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/ptrace.h>
15 #include <linux/slab.h>
16 #include <linux/string.h>
17 #include <linux/timer.h>
18 #include <linux/major.h>
20 #include <linux/ioctl.h>
22 #include <asm/system.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
27 #include <linux/mtd/mtd.h>
28 #include <linux/mtd/iflash.h>
30 /* Parameters that can be set with 'insmod' */
32 static u_long base
= 0xe0000;
33 static int erase_timeout
= 10*HZ
; /* in ticks */
34 static int retry_limit
= 4; /* write retries */
35 static u_long max_tries
= 4096; /* status polling */
37 MODULE_PARM(base
,"l");
38 MODULE_PARM(erase_timeout
, "i");
39 MODULE_PARM(retry_limit
, "i");
40 MODULE_PARM(max_tries
, "i");
42 #define WINDOW_SIZE 0x2000
43 #define WINDOW_MASK (WINDOW_SIZE - 1)
44 #define PAGEREG_LO (WINDOW_SIZE)
45 #define PAGEREG_HI (WINDOW_SIZE + 2)
47 static struct mtd_info
*mymtd
;
48 static struct timer_list flashcard_timer
;
51 #define MAX_FLASH_DEVICES 8
53 /* A flash region is composed of one or more "cells", where we allow
54 simultaneous erases if they are in different cells */
64 struct erase_info
*cur_erases
;
66 u_char devstat
[MAX_FLASH_DEVICES
];
71 static void flashcard_periodic(u_long data
);
72 static int flashcard_erase (struct mtd_info
*mtd
, struct erase_info
*instr
);
73 static int flashcard_read (struct mtd_info
*mtd
, loff_t from
, size_t len
, size_t *retlen
, u_char
*buf
);
74 static int flashcard_write (struct mtd_info
*mtd
, loff_t to
, size_t len
, size_t *retlen
, const u_char
*buf
);
75 static void flashcard_sync (struct mtd_info
*mtd
);
77 static inline void resume_erase(volatile u_char
*addr
);
78 static inline int suspend_erase(volatile u_char
*addr
);
79 static inline int byte_write (volatile u_char
*addr
, u_char byte
);
80 static inline int word_write (volatile u_char
*addr
, __u16 word
);
81 static inline int check_write(volatile u_char
*addr
);
82 static inline void block_erase (volatile u_char
*addr
);
83 static inline int check_erase(volatile u_char
*addr
);
86 #warning This is definitely not SMP safe. Lock the paging mechanism.
89 static u_char
*pagein(struct mtd_info
*mtd
, u_long addr
)
91 struct mypriv
*priv
=mtd
->priv
;
92 u_short page
= addr
>> 13;
94 priv
->baseaddr
[PAGEREG_LO
] = page
& 0xff;
95 priv
->baseaddr
[PAGEREG_HI
] = page
>> 8;
98 return &priv
->baseaddr
[addr
& WINDOW_MASK
];
102 void flashcard_sync (struct mtd_info
*mtd
)
104 struct mypriv
*priv
=mtd
->priv
;
106 flashcard_periodic((u_long
) mtd
);
108 if (priv
->cur_erases
)
109 interruptible_sleep_on(&priv
->wq
);
113 int flashcard_erase (struct mtd_info
*mtd
, struct erase_info
*instr
)
116 struct mypriv
*priv
=mtd
->priv
;
117 struct erase_info
**tmp
=&priv
->cur_erases
;
119 if (instr
->len
!= mtd
->erasesize
)
121 if (instr
->addr
+ instr
->len
> mtd
->size
)
124 pageaddr
=pagein(mtd
,instr
->addr
);
126 instr
->dev
= instr
->addr
>> priv
->devshift
;
127 instr
->cell
= (instr
->addr
- (instr
->dev
<< priv
->devshift
)) / mtd
->erasesize
;
129 instr
->state
= MTD_ERASE_PENDING
;
133 tmp
= &((*tmp
) -> next
);
137 flashcard_periodic((u_long
)mtd
);
142 int flashcard_read (struct mtd_info
*mtd
, loff_t from
, size_t len
, size_t *retlen
, u_char
*buf
)
144 u_char
*pageaddr
=pagein(mtd
,from
);
145 struct mypriv
*priv
=mtd
->priv
;
146 u_char device
= from
>> priv
->devshift
;
147 u_char cell
= (int) (from
- (device
<< priv
->devshift
)) / mtd
->erasesize
;
148 int ret
= 0, timeron
= 0;
150 if ((from
& WINDOW_MASK
) + len
<= WINDOW_SIZE
)
153 *retlen
= WINDOW_SIZE
- (from
& WINDOW_MASK
);
155 if (priv
->devstat
[device
])
158 /* There is an erase in progress or pending for this device. Stop it */
159 timeron
= del_timer(&flashcard_timer
);
161 if (priv
->cur_erases
&& priv
->cur_erases
->cell
== cell
)
164 /* The erase is on the current cell. Just return all 0xff */
165 add_timer(&flashcard_timer
);
168 printk("Cell %d currently erasing. Setting to all 0xff\n",cell
);
169 memset(buf
, 0xff, *retlen
);
172 if (priv
->devstat
[device
] == MTD_ERASING
)
174 ret
= suspend_erase(pageaddr
);
175 priv
->devstat
[device
] = MTD_ERASE_SUSPEND
;
179 printk("flashcard: failed to suspend erase\n");
180 add_timer (&flashcard_timer
);
187 writew(IF_READ_ARRAY
, (u_long
)pageaddr
& ~1);
190 memcpy (buf
, pageaddr
, *retlen
);
192 writew(IF_READ_CSR
, (u_long
)pageaddr
& ~1);
195 if (priv
->devstat
[device
] & MTD_ERASE_SUSPEND
)
197 resume_erase(pageaddr
);
198 priv
->devstat
[device
]=MTD_ERASING
;
202 if (timeron
) add_timer (&flashcard_timer
);
208 int flashcard_write (struct mtd_info
*mtd
, loff_t to
, size_t len
, size_t *retlen
, const u_char
*buf
)
210 struct mypriv
*priv
= (struct mypriv
*)mtd
->priv
;
211 u_char
*endaddr
, *startaddr
;
212 register u_char
*pageaddr
;
213 u_char device
= to
>> priv
->devshift
;
214 /* jiffies_t oldj=jiffies;*/
217 while (priv
->devstat
[device
])
222 if ((to
& WINDOW_MASK
) + len
<= WINDOW_SIZE
)
225 *retlen
= WINDOW_SIZE
- (to
& WINDOW_MASK
);
227 pageaddr
= pagein(mtd
, to
);
228 startaddr
= (u_char
*)((u_long
) pageaddr
& ~1);
229 endaddr
= pageaddr
+(*retlen
);
234 writew(IF_READ_CSR
, startaddr
);
236 /* Make sure it's aligned by reading the first byte if necessary */
239 /* Unaligned access */
245 if (!((u_long
)pageaddr
& 0xf))
248 ret
= byte_write(pageaddr
, cbuf
);
255 for ( ; pageaddr
+ 1 < endaddr
; buf
+= 2, pageaddr
+= 2)
257 /* if ((u_long)pageaddr & 0xf) schedule();*/
259 ret
= word_write(pageaddr
, *(__u16
*)buf
);
264 if (pageaddr
!= endaddr
)
266 /* One more byte to write at the end. */
271 ret
= byte_write(pageaddr
, cbuf
);
276 return check_write(startaddr
);
277 /* printk("Time taken in flashcard_write: %lx jiffies\n",jiffies - oldj);*/
283 /*====================================================================*/
285 static inline int byte_write (volatile u_char
*addr
, u_char byte
)
287 register u_char status
;
288 register u_short i
= 0;
291 status
= readb(addr
);
292 if (status
& CSR_WR_READY
)
294 writeb(IF_WRITE
& 0xff, addr
);
299 } while(i
< max_tries
);
302 printk(KERN_NOTICE
"flashcard: byte_write timed out, status 0x%x\n",status
);
306 static inline int word_write (volatile u_char
*addr
, __u16 word
)
308 register u_short status
;
309 register u_short i
= 0;
312 status
= readw(addr
);
313 if ((status
& CSR_WR_READY
) == CSR_WR_READY
)
315 writew(IF_WRITE
, addr
);
320 } while(i
< max_tries
);
322 printk(KERN_NOTICE
"flashcard: word_write timed out at %p, status 0x%x\n", addr
, status
);
326 static inline void block_erase (volatile u_char
*addr
)
328 writew(IF_BLOCK_ERASE
, addr
);
329 writew(IF_CONFIRM
, addr
);
333 static inline int check_erase(volatile u_char
*addr
)
337 /* writew(IF_READ_CSR, addr);*/
338 status
= readw(addr
);
341 if ((status
& CSR_WR_READY
) != CSR_WR_READY
)
344 if (status
& (CSR_ERA_ERR
| CSR_VPP_LOW
| CSR_WR_ERR
))
346 printk(KERN_NOTICE
"flashcard: erase failed, status 0x%x\n",
354 static inline int suspend_erase(volatile u_char
*addr
)
359 writew(IF_ERASE_SUSPEND
, addr
);
360 writew(IF_READ_CSR
, addr
);
363 status
= readw(addr
);
364 if ((status
& CSR_WR_READY
) == CSR_WR_READY
)
367 } while(i
< max_tries
);
369 printk(KERN_NOTICE
"flashcard: suspend_erase timed out, status 0x%x\n", status
);
374 static inline void resume_erase(volatile u_char
*addr
)
378 writew(IF_READ_CSR
, addr
);
379 status
= readw(addr
);
381 /* Only give resume signal if the erase is really suspended */
382 if (status
& CSR_ERA_SUSPEND
)
383 writew(IF_CONFIRM
, addr
);
386 static inline void reset_block(volatile u_char
*addr
)
391 writew(IF_CLEAR_CSR
, addr
);
393 for (i
= 0; i
< 100; i
++) {
394 writew(IF_READ_CSR
, addr
);
395 status
= readw(addr
);
396 if (status
!= 0xffff) break;
400 writew(IF_READ_CSR
, addr
);
403 static inline int check_write(volatile u_char
*addr
)
405 u_short status
, i
= 0;
407 writew(IF_READ_CSR
, addr
);
410 status
= readw(addr
);
411 if (status
& (CSR_WR_ERR
| CSR_VPP_LOW
))
413 printk(KERN_NOTICE
"flashcard: write failure at %p, status 0x%x\n", addr
, status
);
417 if ((status
& CSR_WR_READY
) == CSR_WR_READY
)
420 } while (i
< max_tries
);
422 printk(KERN_NOTICE
"flashcard: write timed out at %p, status 0x%x\n", addr
, status
);
427 /*====================================================================*/
431 static void flashcard_periodic(unsigned long data
)
433 register struct mtd_info
*mtd
= (struct mtd_info
*)data
;
434 register struct mypriv
*priv
= mtd
->priv
;
435 struct erase_info
*erase
= priv
->cur_erases
;
438 del_timer (&flashcard_timer
);
443 pageaddr
= pagein(mtd
, erase
->addr
);
445 if (erase
->state
== MTD_ERASE_PENDING
)
447 block_erase(pageaddr
);
448 priv
->devstat
[erase
->dev
] = erase
->state
= MTD_ERASING
;
449 erase
->time
= jiffies
;
452 else if (erase
->state
== MTD_ERASING
)
454 /* It's trying to erase. Check whether it's finished */
456 int ret
= check_erase(pageaddr
);
460 /* It's finished OK */
461 priv
->devstat
[erase
->dev
] = 0;
462 priv
->cur_erases
= erase
->next
;
463 erase
->state
= MTD_ERASE_DONE
;
465 (*(erase
->callback
))(erase
);
469 else if (ret
== -EIO
)
471 if (++erase
->retries
> retry_limit
)
473 printk("Failed too many times. Giving up\n");
474 priv
->cur_erases
= erase
->next
;
475 priv
->devstat
[erase
->dev
] = 0;
476 erase
->state
= MTD_ERASE_FAILED
;
478 (*(erase
->callback
))(erase
);
483 priv
->devstat
[erase
->dev
] = erase
->state
= MTD_ERASE_PENDING
;
485 else if (erase
->time
+ erase_timeout
< jiffies
)
487 printk("Flash erase timed out. The world is broken.\n");
489 /* Just ignore and hope it goes away. For a while, read ops will give the CSR
490 and writes won't work. */
492 priv
->cur_erases
= erase
->next
;
493 priv
->devstat
[erase
->dev
] = 0;
494 erase
->state
= MTD_ERASE_FAILED
;
496 (*(erase
->callback
))(erase
);
502 if (priv
->cur_erases
)
504 flashcard_timer
.expires
= jiffies
+ HZ
;
505 add_timer (&flashcard_timer
);
508 wake_up_interruptible(&priv
->wq
);
512 int __init
init_doc1000(void)
518 printk(KERN_NOTICE
"flashcard: No start address for memory device.\n");
522 mymtd
= kmalloc(sizeof(struct mtd_info
), GFP_KERNEL
);
526 printk(KERN_NOTICE
"physmem: Cannot allocate memory for new MTD device.\n");
530 memset(mymtd
,0,sizeof(struct mtd_info
));
532 mymtd
->priv
= (void *) kmalloc (sizeof(struct mypriv
), GFP_KERNEL
);
536 printk(KERN_NOTICE
"physmem: Cannot allocate memory for new MTD device's private data.\n");
544 init_waitqueue_head(&priv
->wq
);
546 memset (priv
,0,sizeof(struct mypriv
));
548 priv
->baseaddr
= phys_to_virt(base
);
549 priv
->numdevices
= 4;
551 mymtd
->name
= "M-Systems DiskOnChip 1000";
553 mymtd
->size
= 0x100000;
554 mymtd
->flags
= MTD_CLEAR_BITS
| MTD_ERASEABLE
;
555 mymtd
->erase
= flashcard_erase
;
557 mymtd
->unpoint
= NULL
;
558 mymtd
->read
= flashcard_read
;
559 mymtd
->write
= flashcard_write
;
561 mymtd
->sync
= flashcard_sync
;
562 mymtd
->erasesize
= 0x10000;
563 // mymtd->interleave = 2;
565 mymtd
->type
= MTD_NORFLASH
;
567 if (add_mtd_device(mymtd
))
569 printk(KERN_NOTICE
"MTD device registration failed!\n");
575 init_timer(&flashcard_timer
);
576 flashcard_timer
.function
= flashcard_periodic
;
577 flashcard_timer
.data
= (u_long
)mymtd
;
581 static void __init
cleanup_doc1000(void)
584 del_mtd_device(mymtd
);
588 module_init(init_doc1000
);
589 module_exit(cleanup_doc1000
);
591 MODULE_LICENSE("GPL");
592 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
593 MODULE_DESCRIPTION("MTD driver for DiskOnChip 1000");