Exemple #1
0
static void
flashreset(void)
{
	Flash *f;
	Flashtype *t;
	char *e;
	int bank;

	for(bank = 0; bank < Nbanks; bank++){
		f = malloc(sizeof(*f));
		if(f == nil){
			print("#F%d: can't allocate Flash data\n", bank);
			return;
		}
		f->cmask = ~(ulong)0;
		if(archflashreset(bank, f) < 0 || f->type == nil ||
		    f->addr == nil){
			free(f);
			return;
		}
		for(t = flash.types; t != nil; t = t->next)
			if(strcmp(f->type, t->name) == 0)
				break;
		if(t == nil){
			iprint("#F%d: no flash driver for type %s (addr %p)\n",
				bank, f->type, f->addr);
			free(f);
			return;
		}
		f->reset = t->reset;
		f->protect = 1;
		if(f->reset(f) == 0){
			flash.card[bank] = f;
			iprint("#F%d: %s addr %#p len %lud width %d interleave %d\n",
//				bank, f->type, PADDR(f->addr), f->size,
				bank, f->type, f->addr, f->size,
				f->width, f->interleave);
			e = flashnewpart(f, "flash", 0, f->size);
			if(e != nil)
				panic("#F%d: couldn't init table: %s", bank, e);
		}else
			iprint("#F%d: %#p: reset failed (%s)\n",
				bank, f->addr, f->type);
	}
}
Exemple #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 */
}