Esempio n. 1
0
//! Handles a monitor command.
void flash_handle_fn( uint8_t const app,
					uint8_t const verb,
					uint32_t const len)
{
		switch(verb) {
			case 0x21:
				eraseflash(cmddataword[0]);
				txdata(app,0,0);
				break;
			case 0x22:
				writeflash(cmddataword[0], cmddata[2]);
				txdata(app,0,0);
				break;
			case 0x23:
				cmddata[0] = readflash(cmddataword[0]);
				txdata(app,0,1);
				break;
		}
}
Esempio n. 2
0
static long	 
flashwrite(Chan *c, void *buf, long n, vlong offset)
{
	Cmdbuf *cb;
	Cmdtab *ct;
	ulong addr, start, end;
	char *e;
	Flashpart *fp;
	Flashregion *r;
	Flash *f;

	f = flash.card[c->dev];
	fp = &f->part[PART(c->qid.path)];
	if(fp->name == nil)
		error(Egreg);
	switch(TYPE(c->qid.path)){
	case Qdata:
		if(f->write == nil)
			error(Eperm);
		offset += fp->start;
		if(offset >= fp->end)
			return 0;
		if(offset+n > fp->end)
			n = fp->end - offset;
		n = writeflash(f, offset, buf, n);
		if(n < 0)
			error(Eio);
		return n;
	case Qctl:
		cb = parsecmd(buf, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, flashcmds, nelem(flashcmds));
		switch(ct->index){
		case CMerase:
			if(strcmp(cb->f[1], "all") != 0){
				addr = flashaddr(f, fp, cb->f[1]);
				r = flashregion(f, addr);
				if(r == nil)
					error("nonexistent flash region");
				if(addr%r->erasesize != 0)
					error("invalid erase block address");
				eraseflash(f, r, addr);
			}else if(fp->start == 0 && fp->end == f->size && f->eraseall != nil){
				eraseflash(f, nil, 0);
			}else{
				for(addr = fp->start; addr < fp->end; addr += r->erasesize){
					r = flashregion(f, addr);
					if(r == nil)
						error("nonexistent flash region");
					if(addr%r->erasesize != 0)
						error("invalid erase block address");
					eraseflash(f, r, addr);
				}
			}
			break;
		case CMadd:
			if(cb->nf < 3)
				error(Ebadarg);
			start = flashaddr(f, fp, cb->f[2]);
			if(cb->nf > 3 && strcmp(cb->f[3], "end") != 0)
				end = flashaddr(f, fp, cb->f[3]);
			else
				end = fp->end;
			if(start > end || start >= fp->end || end > fp->end)
				error(Ebadarg);
			e = flashnewpart(f, cb->f[1], start, end);
			if(e != nil)
				error(e);
			break;
		case CMremove:
			/* TO DO */
			break;
		case CMprotectboot:
			if(cb->nf > 1 && strcmp(cb->f[1], "off") == 0)
				f->protect = 0;
			else
				f->protect = 1;
			break;
		case CMsync:
			/* TO DO? */
			break;
		default:
			error(Ebadarg);
		}
		poperror();
		free(cb);
		return n;
	}
	error(Egreg);
	return 0;		/* not reached */
}