| plan 9 kernel history: overview | file list | diff list |
2000/1209/bitsy/devflash.c (diff list | history)
| 2000/1207/sys/src/9/bitsy/devflash.c:71,76 – 2000/1209/sys/src/9/bitsy/devflash.c:71,81 (short | long | prev | next) | ||
| 2000/1117 | ulong *wb; /* staging area for write buffer */ } flash; | |
| 2000/1111 | ||
| 2000/1209 | enum { Maxwchunk= 1024, /* maximum chunk written by one call to falg->write */ }; | |
| 2000/1117 | /* * common flash interface */ | |
| 2000/1207/sys/src/9/bitsy/devflash.c:128,134 – 2000/1209/sys/src/9/bitsy/devflash.c:133,139 | ||
| 2000/1117 | addr += flash.r[q].size*flash.r[q].n; flash.r[q].end = addr; } | |
| 2000/1209 | flash.wb = malloc(flash.wbsize>1024 ? flash.wbsize : 1024); | |
| 2000/1117 | } | |
| 2000/1111 | /* | |
| 2000/1207/sys/src/9/bitsy/devflash.c:506,512 – 2000/1209/sys/src/9/bitsy/devflash.c:511,520 | ||
| 2000/1117 | m = blockend(off) - off; if(m > end - p) m = end - p; | |
| 2000/1209 | if(m > Maxwchunk) m = Maxwchunk; memmove(flash.wb, p, m); (*flash.alg->write)(flash.wb, m, off); | |
| 2000/1117 | off += m; } | |
| 2000/1207/sys/src/9/bitsy/devflash.c:561,567 – 2000/1209/sys/src/9/bitsy/devflash.c:569,590 | ||
| 2000/1111 | devwstat, | |
| 2000/1107 | }; | |
| 2000/1117 | ||
| 2000/1209 | enum { /* status register */ ISEs_lockerr= 1<<1, ISEs_powererr= 1<<3, ISEs_progerr= 1<<4, ISEs_eraseerr= 1<<5, ISEs_ready= 1<<7, ISEs_err= (ISEs_lockerr|ISEs_powererr|ISEs_progerr|ISEs_eraseerr), | |
| 2000/1117 | ||
| 2000/1209 | /* extended status register */ ISExs_bufavail= 1<<7, }; | |
| 2000/1117 | /* intel/sharp extended command set */ static void ise_reset(void) | |
| 2000/1207/sys/src/9/bitsy/devflash.c:588,603 – 2000/1209/sys/src/9/bitsy/devflash.c:611,626 | ||
| 2000/1117 | { char err[ERRLEN]; | |
| 2000/1209 | if(status & (ISEs_lockerr)){ sprint(err, "flash%d: block locked %lux", bank, status); | |
| 2000/1117 | error(err); } | |
| 2000/1209 | if(status & (ISEs_powererr)){ sprint(err, "flash%d: low prog voltage %lux", bank, status); | |
| 2000/1117 | error(err); } | |
| 2000/1209 | if(status & (ISEs_progerr|ISEs_eraseerr)){ sprint(err, "flash%d: i/o error %lux", bank, status); | |
| 2000/1117 | error(err); } } | |
| 2000/1207/sys/src/9/bitsy/devflash.c:615,621 – 2000/1209/sys/src/9/bitsy/devflash.c:638,644 | ||
| 2000/1117 | start = m->ticks; do { x = flash.p[addr]; | |
| 2000/1209 | if((x & mirror(ISEs_ready)) == mirror(ISEs_ready)) | |
| 2000/1117 | break; } while(TK2MS(m->ticks-start) < 1500); flashprogpower(0); | |
| 2000/1207/sys/src/9/bitsy/devflash.c:627,633 – 2000/1209/sys/src/9/bitsy/devflash.c:650,656 | ||
| 2000/1117 | ise_reset(); } /* | |
| 2000/1209 | * the flash spec claimes writing goes faster if we use | |
| 2000/1117 | * the write buffer. We fill the write buffer and then * issue the write request. After the write request, * subsequent reads will yield the status register or, | |
| 2000/1207/sys/src/9/bitsy/devflash.c:637,680 – 2000/1209/sys/src/9/bitsy/devflash.c:660,719 | ||
| 2000/1117 | * On timeout, we issue a read status register request so * that the status register can be read no matter how we * exit. | |
| 2000/1209 | * * returns the status. | |
| 2000/1117 | */ | |
| 2000/1209 | static ulong ise_wbwrite(ulong *p, int n, ulong off, ulong baddr, ulong *status) | |
| 2000/1117 | { | |
| 2000/1209 | ulong x, start; | |
| 2000/1117 | int i; | |
| 2000/1209 | int s; | |
| 2000/1117 |
| |
| 2000/1209 | s = splhi(); | |
| 2000/1117 | /* request write buffer mode */ | |
| 2000/1209 | flash.p[baddr] = mirror(0xe8); | |
| 2000/1117 | /* look at extended status reg for status */ | |
| 2000/1209 | if((flash.p[baddr] & mirror(1<<7)) == mirror(1<<7)) | |
| 2000/1117 | break; | |
| 2000/1209 | splx(s); | |
| 2000/1117 | /* didn't work, keep trying for 2 secs */ if(TK2MS(m->ticks-start) > 2000){ /* set up to read status */ | |
| 2000/1209 | flash.p[baddr] = mirror(0x70); *status = flash.p[baddr]; pprint("write buffered cmd timed out\n"); | |
| 2000/1117 | return -1; } } /* fill write buffer */ | |
| 2000/1209 | flash.p[baddr] = mirror(n-1); | |
| 2000/1117 | for(i = 0; i < n; i++) flash.p[off+i] = *p++; /* program from buffer */ | |
| 2000/1209 | flash.p[baddr] = mirror(0xd0); splx(s); | |
| 2000/1117 |
| |
| 2000/1209 | /* wait till the programming is done */ start = m->ticks; for(;;) { x = *status = flash.p[baddr]; /* read status register */ if((x & mirror(ISEs_ready)) == mirror(ISEs_ready)) break; if(TK2MS(m->ticks-start) > 2000){ pprint("read status timed out\n"); return -1; } } if(x & mirror(ISEs_err)) return -1; | |
| 2000/1117 | return n; } | |
| 2000/1207/sys/src/9/bitsy/devflash.c:683,696 – 2000/1209/sys/src/9/bitsy/devflash.c:722,736 | ||
| 2000/1117 | { ulong *p, *end; int i, wbsize; | |
| 2000/1209 | ulong x, baddr; | |
| 2000/1117 | /* everything in terms of ulongs */ wbsize = flash.wbsize>>2; | |
| 2000/1209 | baddr = blockstart(off); | |
| 2000/1117 | off >>= 2; n >>= 2; p = a; | |
| 2000/1209 | baddr >>= 2; | |
| 2000/1117 | /* first see if write will succeed */ for(i = 0; i < n; i++) | |
| 2000/1207/sys/src/9/bitsy/devflash.c:715,721 – 2000/1209/sys/src/9/bitsy/devflash.c:755,761 | ||
| 2000/1117 | if(i > end - p) i = end - p; | |
| 2000/1209 | if(ise_wbwrite(p, i, off, baddr, &x) < 0) | |
| 2000/1117 | break; off += i; | |
| 2000/1207/sys/src/9/bitsy/devflash.c:722,735 – 2000/1209/sys/src/9/bitsy/devflash.c:762,767 | ||
| 2000/1117 | p += i; i = wbsize; } | |