Ejemplo n.º 1
0
int
fwormwrite(Device *d, Off b, void *c)
{
	Iobuf *p;
	Device *fdev;
	Devsize l;

	if(DEBUG)
		print("fworm write %lld\n", (Wideoff)b);
	fdev = FDEV(d);
	l = devsize(fdev);
	l -= l/(BUFSIZE*8) + 1;
	if(b >= l)
		panic("fworm: wbounds %lld", (Wideoff)b);
	l += b/(BUFSIZE*8);

	p = getbuf(fdev, l, Brd|Bmod|Bres);
	if(!p || checktag(p, Tvirgo, l))
		panic("fworm: checktag %lld", (Wideoff)l);
	l = b % (BUFSIZE*8);
	if((p->iobuf[l/8] & (1<<(l%8)))) {
		putbuf(p);
		print("fworm: write %lld\n", (Wideoff)b);
		return 1;
	}
	p->iobuf[l/8] |= 1<<(l%8);
	putbuf(p);
	return devwrite(fdev, b, c);
}
Ejemplo n.º 2
0
void dputs(void *handle, char *s){
	size_t buflen = (strlen(s) * 2);
	char *buf = (char*)malloc(buflen);
	for(size_t i = 0; i < buflen; ++i){
		buf[i * 2] = s[i];
		buf[(i * 2) + 1] = 0x07;
	}
	devwrite(handle, buflen, buf);
	free(buf);
}
Ejemplo n.º 3
0
void
putbuf(Iobuf *p)
{

	if(canqlock(p))
		print("buffer not locked %Z(%lld)\n", p->dev, (Wideoff)p->addr);
	if(p->flags & Bimm) {
		if(!(p->flags & Bmod))
			print("imm and no mod %Z(%lld)\n",
				p->dev, (Wideoff)p->addr);
		if(!devwrite(p->dev, p->addr, p->iobuf))
			p->flags &= ~(Bmod|Bimm);
	}
	iobufunmap(p);
	qunlock(p);
}
Ejemplo n.º 4
0
/*
 * syncblock tries to put out a block per hashline
 * returns 0 all done,
 * returns 1 if it missed something
 */
int
syncblock(void)
{
	Iobuf *p, *s, *q;
	Hiob *hp;
	int32_t h;
	int flag;

	flag = 0;
	for(h=0; h<nhiob; h++) {
		q = 0;
		hp = &hiob[h];
		lock(hp);
		s = hp->link;
		for(p=s;;) {
			if(p->flags & Bmod) {
				if(q)
					flag = 1;	/* more than 1 mod/line */
				q = p;
			}
			p = p->fore;
			if(p == s)
				break;
		}
		unlock(hp);
		if(q) {
			if(!canqlock(q)) {
				flag = 1;		/* missed -- was locked */
				continue;
			}
			if(!(q->flags & Bmod)) {
				qunlock(q);
				continue;
			}
			if(iobufmap(q)) {
				if(!devwrite(q->dev, q->addr, q->iobuf))
					q->flags &= ~(Bmod|Bimm);
				iobufunmap(q);
			} else
				flag = 1;
			qunlock(q);
		}
	}
	return flag;
}
Ejemplo n.º 5
0
/* copy device from src to dest */
static int
dodevcopy(void)
{
	Device *from, *to;
	Iobuf *p;
	Off a;
	Devsize lim, tosize;

	/*
	 * convert config strings into Devices.
	 */
	from = iconfig(src);
	if(f.error || from == nil) {
		print("bad src device %s\n", src);
		return -1;
	}
	to = iconfig(dest);
	if(f.error || to == nil) {
		print("bad dest device %s\n", dest);
		return -1;
	}

	/*
	 * initialise devices, size them, more sanity checking.
	 */

	devinit(from);
	lim = devsize(from);
	if(lim == 0)
		panic("no blocks to copy on %Z", from);
	devinit(to);
	tosize = devsize(to);
	if(tosize == 0)
		panic("no blocks to copy on %Z", to);

	/* use smaller of the device sizes */
	if (tosize < lim)
		lim = tosize;

	print("copy %Z to %Z in 8 seconds\n", from, to);
	delay(8000);
	if (userabort("preparing to copy"))
		return -1;
	print("copying dev: %lld blocks from %Z to %Z\n", (Wideoff)lim,
		from, to);

	/*
	 * Copy all blocks, a block at a time.
	 */

	for (a = 0; a < lim; a++) {
		if (userabort("copy"))
			break;
		p = getbuf(from, a, Brd);
		/*
		 * if from is a real WORM device, we'll get errors trying to
		 * read unwritten blocks, but the unwritten blocks need not
		 * be contiguous.
		 */
		if (p == 0) {
			print("%lld not written yet; can't read\n", (Wideoff)a);
			continue;
		}
		if (to != 0 && devwrite(to, p->addr, p->iobuf) != 0) {
			print("out block %lld: write error; bailing",
				(Wideoff)a);
			break;
		}
		putbuf(p);
		if(a % 20000 == 0)
			print("block %lld %T\n", (Wideoff)a, time(nil));
	}

	/*
	 * wrap up: sync target
	 */
	print("copied %lld blocks from %Z to %Z\n", (Wideoff)a, from, to);
	sync("devcopy");
	return 0;
}
Ejemplo n.º 6
0
/* copy worm fs from "main"'s inner worm to "output" */
static void
dowormcopy(void)
{
	Filsys *f1, *f2;
	Device *fdev, *from, *to = nil;
	Iobuf *p;
	Off a;
	Devsize lim;

	/*
	 * convert file system names into Filsyss and Devices.
	 */

	f1 = fsstr("main");
	if(f1 == nil)
		panic("main file system missing");
	fdev = f1->dev;
	from = wormof(fdev);			/* fake worm special */
	if (from->type != Devfworm && from->type != Devcw) {
		print("main file system is not a worm; copyworm may not do what you want!\n");
		print("waiting for 20 seconds...\n");
		delay(20000);
	}

	f2 = fsstr("output");
	if(f2 == nil) {
		print("no output file system - check only\n\n");
		print("reading worm from %Z (worm %Z)\n", fdev, from);
	} else {
		to = f2->dev;
		print("\ncopying worm from %Z (worm %Z) to %Z, starting in 8 seconds\n",
			fdev, from, to);
		delay(8000);
	}
	if (userabort("preparing to copy"))
		return;

	/*
	 * initialise devices, size them, more sanity checking.
	 */

	devinit(from);
	if (0 && fdev != from) {
		devinit(fdev);
		print("debugging, sizing %Z first\n", fdev);
		writtensize(fdev);
	}
	lim = writtensize(from);
	if(lim == 0)
		panic("no blocks to copy on %Z", from);
	if (to) {
		print("reaming %Z in 8 seconds\n", to);
		delay(8000);
		if (userabort("preparing to ream & copy"))
			return;
		devream(to, 0);
		devinit(to);
		print("copying worm: %lld blocks from %Z to %Z\n",
			(Wideoff)lim, from, to);
	}
	/* can't read to's blocks in case to is a real WORM device */

	/*
	 * Copy written fs blocks, a block at a time (or just read
	 * if no "output" fs).
	 */

	for (a = 0; a < lim; a++) {
		if (userabort("copy"))
			break;
		p = getbuf(from, a, Brd);
		/*
		 * if from is a real WORM device, we'll get errors trying to
		 * read unwritten blocks, but the unwritten blocks need not
		 * be contiguous.
		 */
		if (p == 0) {
			print("%lld not written yet; can't read\n", (Wideoff)a);
			continue;
		}
		if (to != 0 && devwrite(to, p->addr, p->iobuf) != 0) {
			print("out block %lld: write error; bailing",
				(Wideoff)a);
			break;
		}
		putbuf(p);
		if(a % 20000 == 0)
			print("block %lld %T\n", (Wideoff)a, time(nil));
	}

	/*
	 * wrap up: sync target, loop
	 */
	print("copied %lld blocks from %Z to %Z\n", (Wideoff)a, from, to);
	sync("wormcopy");
	delay(2000);
	print("looping; reset the machine at any time.\n");
	for (; ; )
		continue;		/* await reset */
}
Ejemplo n.º 7
0
Archivo: sub.c Proyecto: npe9/harvey
int
devwrite(Device *d, Off b, void *c)
{
	int e;

	/*
	 * set readonly to non-0 to prevent all writes;
	 * mainly for trying dangerous experiments.
	 */
	if (readonly)
		return 0;
	for (;;)
		switch(d->type) {
		case Devcw:
			return cwwrite(d, b, c);

		case Devjuke:
			d = d->j.m;
			break;

		case Devro:
			print("write to ro device %Z(%lld)\n", d, (Wideoff)b);
			return 1;

		case Devwren:
			return wrenwrite(d, b, c);

		case Devworm:
		case Devlworm:
			return wormwrite(d, b, c);

		case Devfworm:
			return fwormwrite(d, b, c);

		case Devmcat:
			return mcatwrite(d, b, c);

		case Devmlev:
			return mlevwrite(d, b, c);

		case Devmirr:
			return mirrwrite(d, b, c);

		case Devpart:
			return partwrite(d, b, c);

		case Devswab:
			swab(c, 1);
			e = devwrite(d->swab.d, b, c);
			swab(c, 0);
			return e;

		case Devnone:
			/* checktag() can generate blocks with type devnone */
			return 0;
		default:
			panic("illegal device in devwrite: %Z %lld",
				d, (Wideoff)b);
			return 1;
		}
}
Ejemplo n.º 8
0
Iobuf*
getbuf(Device *d, Off addr, int flag)
{
	Iobuf *p, *s;
	Hiob *hp;
	Off h;

	if(DEBUG)
		print("getbuf %Z(%lld) f=%x\n", d, (Wideoff)addr, flag);
	h = addr + (Off)(uintptr)d*1009;
	if(h < 0)
		h = ~h;
	h %= nhiob;
	hp = &hiob[h];

loop:
	lock(hp);

/*
 * look for it in the active list
 */
	s = hp->link;
	for(p=s;;) {
		if(p->addr == addr && p->dev == d) {
			if(p != s) {
				p->back->fore = p->fore;
				p->fore->back = p->back;
				p->fore = s;
				p->back = s->back;
				s->back = p;
				p->back->fore = p;
				hp->link = p;
			}
			unlock(hp);
			qlock(p);
			if(p->addr != addr || p->dev != d || iobufmap(p) == 0) {
				qunlock(p);
				goto loop;
			}
			p->flags |= flag;
			return p;
		}
		p = p->fore;
		if(p == s)
			break;
	}
	if(flag & Bprobe) {
		unlock(hp);
		return 0;
	}

/*
 * not found
 * take oldest unlocked entry in this queue
 */
xloop:
	p = s->back;
	if(!canqlock(p)) {
		if(p == hp->link) {
			unlock(hp);
			print("iobuf all locked\n");
			goto loop;
		}
		s = p;
		goto xloop;
	}

	/*
	 * its dangerous to flush the pseudo
	 * devices since they recursively call
	 * getbuf/putbuf. deadlock!
	 */
	if(p->flags & Bres) {
		qunlock(p);
		if(p == hp->link) {
			unlock(hp);
			print("iobuf all reserved\n");
			goto loop;
		}
		s = p;
		goto xloop;
	}
	if(p->flags & Bmod) {
		unlock(hp);
		if(iobufmap(p)) {
			if(!devwrite(p->dev, p->addr, p->iobuf))
				p->flags &= ~(Bimm|Bmod);
			iobufunmap(p);
		}
		qunlock(p);
		goto loop;
	}
	hp->link = p;
	p->addr = addr;
	p->dev = d;
	p->flags = flag;
	unlock(hp);
	if(iobufmap(p))
		if(flag & Brd) {
			if(!devread(p->dev, p->addr, p->iobuf))
				return p;
			iobufunmap(p);
		} else
			return p;
	else
		print("iobuf cant map buffer\n");
	p->flags = 0;
	p->dev = devnone;
	p->addr = -1;
	qunlock(p);
	return 0;
}
Ejemplo n.º 9
0
int
ethertxpkt(int ctlrno, Etherpkt *pkt, int len, int timo)
{
	USED(timo);
	return devwrite(ctlrno, (uchar*)pkt, len, 0);
}
Ejemplo n.º 10
0
/* out */ /*{{{*/
void out(unsigned int port, unsigned char byte)
{
  switch (port) 
  {
    /* COND */ /*{{{*/
    case COND: devwrite(conout,byte); break;
    /*}}}*/
    /* AUXD */ /*{{{*/
    case AUXD: devwrite(pun,byte); break;
    /*}}}*/
    /* PRTD */ /*{{{*/
    case PRTD: devwrite(lst,byte); break;
    /*}}}*/
    /* FDCD */ /*{{{*/
    case FDCD: if (byte>15 || disks[byte]->fd==-1) status=FDCX_NODRIVE; else { drive=byte; status=FDCX_OK; } break;
    /*}}}*/
    /* FDCTL */ /*{{{*/
    case FDCTL: track=(track&0xff00)|byte; break;
    /*}}}*/
    /* FDCTH */ /*{{{*/
    case FDCTH: track=(track&0xff)|(((unsigned int)byte)<<8); break;
    /*}}}*/
    /* FDCS */ /*{{{*/
    case FDCS: sector=byte; break;
    /*}}}*/
    /* FDCO */ /*{{{*/
    case FDCO:
/*
 *      I/O handler for write FDC command:
 *      transfer one sector in the wanted direction,
 *      0 = read, 1 = write
 *
 *      The status byte of the FDC is set as follows:
 *        0 - ok
 *        1 - illegal drive
 *        2 - illegal track
 *        3 - illegal sector
 *        4 - seek error
 *        5 - read error
 *        6 - write error
 *        7 - illegal command to FDC
 *        9 - illegal dma address
    */
    {
      register int size;

      if (disks[drive]->fd==-1) { status=FDCX_NODRIVE; return; }
      if (track>disks[drive]->tracks) fprintf(stderr,"YAZE: track %04x selected\r\n",track);
      if (track>disks[drive]->tracks) { status=FDCX_NOTRACK; return; }
      if (sector>disks[drive]->sectors) { status=FDCX_NOSECTOR; return; }
      size=disks[drive]->secsize;
      if (dma+size>(64*1024)) { status=FDCX_DMAFAIL; return; }
      if (lseek(disks[drive]->fd, (((off_t)track)*((off_t)disks[drive]->sectors)+(off_t)(sector-1))*(off_t)size,SEEK_SET)==(off_t)-1) { status=FDCX_SEEKFAIL; return; }
      switch (byte)
      {
        case FDCO_READ:
        status=(read(disks[drive]->fd,&ram[dma],size)==size ? FDCX_OK : FDCX_READFAIL);
        benice=0;
        break;
        case FDCO_WRITE:
        status=(write(disks[drive]->fd,&ram[dma],size)==size ? FDCX_OK : FDCX_WRITEFAIL);
        benice=0;
        break;
        default:
        status=FDCX_NOCMD;
        break;
      }
      break;
    }
    /*}}}*/
    /* DMAL */ /*{{{*/
    case DMAL: dma=(dma&0xff00)|byte; break;
    /*}}}*/
    /* DMAH */ /*{{{*/
    case DMAH: dma=(dma&0xff)|(((unsigned int)byte)<<8); break;
    /*}}}*/
    /* CLKC */ /*{{{*/
    case CLKC: clkcmd=byte; break;
    /*}}}*/
    /* HALT */ /*{{{*/
    case HALT: do_halt=1; break;
    /*}}}*/
  }
}