Пример #1
0
static int
sdinitpart(SDunit* unit)
{
	int nf;
	uvlong start, end;
	char *f[4], *p, *q, buf[10];

	if(unit->sectors > 0){
		unit->sectors = unit->secsize = 0;
		sdincvers(unit);
	}

	/* device must be connected or not; other values are trouble */
	if(unit->inquiry[0] & 0xC0)	/* see SDinq0periphqual */
		return 0;
	switch(unit->inquiry[0] & SDinq0periphtype){
	case SDperdisk:
	case SDperworm:
	case SDpercd:
	case SDpermo:
		break;
	default:
		return 0;
	}

	if(unit->dev->ifc->online)
		unit->dev->ifc->online(unit);
	if(unit->sectors){
		sdincvers(unit);
		sdaddpart(unit, "data", 0, unit->sectors);

		/*
		 * Use partitions passed from boot program,
		 * e.g.
		 *	sdC0part=dos 63 123123/plan9 123123 456456
		 * This happens before /boot sets hostname so the
		 * partitions will have the null-string for user.
		 * The gen functions patch it up.
		 */
		snprint(buf, sizeof buf, "%spart", unit->name);
		for(p = getconf(buf); p != nil; p = q){
			if(q = strchr(p, '/'))
				*q++ = '\0';
			nf = tokenize(p, f, nelem(f));
			if(nf < 3)
				continue;

			start = strtoull(f[1], 0, 0);
			end = strtoull(f[2], 0, 0);
			if(!waserror()){
				sdaddpart(unit, f[0], start, end);
				poperror();
			}
		}
	}

	return 1;
}
Пример #2
0
static int
sdinitpart(SDunit* unit)
{
	int nf;
	uvlong start, end;
	char *f[4], *p, *q, buf[10];

	if(unit->sectors > 0){
		unit->sectors = unit->secsize = 0;
		sdincvers(unit);
	}

	if(unit->inquiry[0] & 0xC0)
		return 0;
	switch(unit->inquiry[0] & 0x1F){
	case 0x00:			/* DA */
	case 0x04:			/* WORM */
	case 0x05:			/* CD-ROM */
	case 0x07:			/* MO */
		break;
	default:
		return 0;
	}

	if(unit->dev->ifc->online)
		unit->dev->ifc->online(unit);
	if(unit->sectors){
		sdincvers(unit);
		sdaddpart(unit, "data", 0, unit->sectors);

		/*
		 * Use partitions passed from boot program,
		 * e.g.
		 *	sdC0part=dos 63 123123/plan9 123123 456456
		 * This happens before /boot sets hostname so the
		 * partitions will have the null-string for user.
		 * The gen functions patch it up.
		 */
		snprint(buf, sizeof buf, "%spart", unit->name);
		for(p = getconf(buf); p != nil; p = q){
			if(q = strchr(p, '/'))
				*q++ = '\0';
			nf = tokenize(p, f, nelem(f));
			if(nf < 3)
				continue;

			start = strtoull(f[1], 0, 0);
			end = strtoull(f[2], 0, 0);
			if(!waserror()){
				sdaddpart(unit, f[0], start, end);
				poperror();
			}
		}
	}

	return 1;
}
Пример #3
0
static int
sdinitpart(SDunit* unit)
{
	unit->sectors = unit->secsize = 0;
	unit->npart = 0;
	if(unit->part){
		free(unit->part);
		unit->part = nil;
	}

	if(unit->inquiry[0] & 0xC0)
		return 0;
	switch(unit->inquiry[0] & 0x1F){
	case 0x00:			/* DA */
	case 0x04:			/* WORM */
	case 0x05:			/* CD-ROM */
	case 0x07:			/* MO */
		break;
	default:
		return 0;
	}

	if(unit->dev->ifc->online == nil || unit->dev->ifc->online(unit) == 0)
		return 0;
	sdaddpart(unit, "data", 0, unit->sectors);
	return 1;
}
Пример #4
0
Файл: part.c Проект: npe9/harvey
static void
p9part(SDunit *unit, char *name)
{
	SDpart *p;
	char *field[4], *line[Npart+1];
	uint32_t start, end;
	int i, n;

	p = sdfindpart(unit, name);
	if(p == nil)
		return;

	if(tsdbio(unit, p, partbuf, unit->secsize, 0) < 0)
		return;
	partbuf[unit->secsize-1] = '\0';

	if(strncmp((char*)partbuf, "part ", 5) != 0)
		return;

	n = getfields((char*)partbuf, line, Npart+1, '\n');
	if(n == 0)
		return;
	for(i = 0; i < n && unit->npart < SDnpart; i++){
		if(strncmp(line[i], "part ", 5) != 0)
			break;
		if(getfields(line[i], field, 4, ' ') != 4)
			break;
		start = strtoul(field[2], 0, 0);
		end = strtoul(field[3], 0, 0);
		if(start >= end || end > unit->sectors)
			break;
		sdaddpart(unit, field[1], p->start+start, p->start+end);
	}
}
Пример #5
0
/*
 * look for a plan 9 partition table on drive `unit' in the second
 * sector (sector 1) of partition `name'.
 * if found, add the partitions defined in the table.
 */
static void
p9part(SDunit *unit, char *name)
{
	SDpart *p;
	char *field[4], *line[Npart+1];
	uvlong start, end;
	int i, n;

	dprint("p9part %s %s\n", unit->name, name);
	p = sdfindpart(unit, name);
	if(p == nil)
		return;

	if(sdreadblk(unit, p, partbuf, unit->secsize, 0) < 0)
		return;
	partbuf[unit->secsize-1] = '\0';

	if(strncmp((char*)partbuf, "part ", 5) != 0)
		return;

	n = gettokens((char*)partbuf, line, Npart+1, "\n");
	if(n == 0)
		return;
	for(i = 0; i < n && unit->npart < SDnpart; i++){
		if(strncmp(line[i], "part ", 5) != 0)
			break;
		if(gettokens(line[i], field, 4, " ") != 4)
			break;
		start = strtoull(field[2], 0, 0);
		end   = strtoull(field[3], 0, 0);
		if(start >= end || end > unit->sectors)
			break;
		sdaddpart(unit, field[1], p->start+start, p->start+end);
	}
}
Пример #6
0
static void
oldp9part(SDunit *unit)
{
	SDpart *pp;
	char *field[3], *line[Npart+1];
	ulong n;
	uvlong start, end;
	int i;

	/*
	 *  We have some partitions already.
	 */
	pp = &unit->part[unit->npart];

	/*
	 * We prefer partition tables on the second to last sector,
	 * but some old disks use the last sector instead.
	 */
	strcpy(pp->name, "partition");
	pp->start = unit->sectors - 2;
	pp->end = unit->sectors - 1;

	dprint("oldp9part %s\n", unit->name);
	if(sdreadblk(unit, pp, partbuf, 0, 0) < 0)
		return;

	if(strncmp((char*)partbuf, MAGIC, sizeof(MAGIC)-1) != 0) {
		/* not found on 2nd last sector; look on last sector */
		pp->start++;
		pp->end++;
		if(sdreadblk(unit, pp, partbuf, 0, 0) < 0)
			return;
		if(strncmp((char*)partbuf, MAGIC, sizeof(MAGIC)-1) != 0)
			return;
		print("%s: using old plan9 partition table on last sector\n", unit->name);
	}else
		print("%s: using old plan9 partition table on 2nd-to-last sector\n", unit->name);

	/* we found a partition table, so add a partition partition */
	unit->npart++;
	partbuf[unit->secsize-1] = '\0';

	/*
	 * parse partition table
	 */
	n = gettokens((char*)partbuf, line, Npart+1, "\n");
	if(n && strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){
		for(i = 1; i < n && unit->npart < SDnpart; i++){
			if(gettokens(line[i], field, 3, " ") != 3)
				break;
			start = strtoull(field[1], 0, 0);
			end = strtoull(field[2], 0, 0);
			if(start >= end || end > unit->sectors)
				break;
			sdaddpart(unit, field[0], start, end);
		}
	}
}
Пример #7
0
Файл: part.c Проект: npe9/harvey
/*
 * To facilitate booting from CDs, we create a partition for
 * the boot floppy image embedded in a bootable CD.
 */
static int
part9660(SDunit *unit)
{
	uint8_t buf[2048];
	uint32_t a, n;
	uint8_t *p;

	if(unit->secsize != 2048)
		return -1;

	if(sdbio(unit, &unit->part[0], buf, 2048, 17*2048) < 0)
		return -1;

	if(buf[0] || strcmp((char*)buf+1, "CD001\x01EL TORITO SPECIFICATION") != 0)
		return -1;


	p = buf+0x47;
	a = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);

	if(sdbio(unit, &unit->part[0], buf, 2048, a*2048) < 0)
		return -1;

	if(memcmp(buf, "\x01\x00\x00\x00", 4) != 0
	|| memcmp(buf+30, "\x55\xAA", 2) != 0
	|| buf[0x20] != 0x88)
		return -1;

	p = buf+0x28;
	a = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);

	switch(buf[0x21]){
	case 0x01:
		n = 1200*1024;
		break;
	case 0x02:
		n = 1440*1024;
		break;
	case 0x03:
		n = 2880*1024;
		break;
	default:
		return -1;
	}
	n /= 2048;

	print("found partition %s!cdboot; %lud+%lud\n", unit->name, a, n);
	sdaddpart(unit, "cdboot", a, a+n);
	return 0;
}
Пример #8
0
static void
psdaddpart(PSDunit* unit, char* name, uvlong start, uvlong end)
{
	int len, nw;

	sdaddpart(unit, name, start, end);

	/* update devsd's in-memory partition table. */
	len = snprint(buf, sizeof buf, "part %s %lld %lld\n", name, start, end);
	nw = devtab[unit->ctlc->type]->write(unit->ctlc, buf, len,
		unit->ctlc->offset);
	if (nw != len)
		print("can't update devsd's partition table\n");
	if (Debugboot)
		print("part %s %lld %lld\n", name, start, end);
}
Пример #9
0
Файл: part.c Проект: npe9/harvey
/*
 * Fetch the first dos and all plan9 partitions out of the MBR partition table.
 * We return -1 if we did not find a plan9 partition.
 */
static int
mbrpart(SDunit *unit)
{
	Dospart *dp;
	uint32_t taboffset, start, end;
	uint32_t firstxpart, nxtxpart;
	int havedos, i, nplan9;
	char name[10];

	taboffset = 0;
	dp = (Dospart*)&mbrbuf[0x1BE];
	if(1) {
		/* get the MBR (allowing for DMDDO) */
		if(tsdbio(unit, &unit->part[0], mbrbuf, (int64_t)taboffset*unit->secsize, 1) < 0)
			return -1;
		for(i=0; i<4; i++)
			if(dp[i].type == DMDDO) {
				if(trace)
					print("DMDDO partition found\n");
				taboffset = 63;
				if(tsdbio(unit, &unit->part[0], mbrbuf, (int64_t)taboffset*unit->secsize, 1) < 0)
					return -1;
				i = -1;	/* start over */
			}
	}

	/*
	 * Read the partitions, first from the MBR and then
	 * from successive extended partition tables.
	 */
	nplan9 = 0;
	havedos = 0;
	firstxpart = 0;
	for(;;) {
		if(tsdbio(unit, &unit->part[0], mbrbuf, (int64_t)taboffset*unit->secsize, 1) < 0)
			return -1;
		if(trace) {
			if(firstxpart)
				print("%s ext %lud ", unit->name, taboffset);
			else
				print("%s mbr ", unit->name);
		}
		nxtxpart = 0;
		for(i=0; i<4; i++) {
			if(trace)
				print("dp %d...", dp[i].type);
			start = taboffset+GLONG(dp[i].start);
			end = start+GLONG(dp[i].len);

			if(dp[i].type == PLAN9) {
				if(nplan9 == 0)
					strcpy(name, "plan9");
				else
					sprint(name, "plan9.%d", nplan9);
				sdaddpart(unit, name, start, end);
				p9part(unit, name);
				nplan9++;
			}

			/*
			 * We used to take the active partition (and then the first
			 * when none are active).  We have to take the first here,
			 * so that the partition we call ``dos'' agrees with the
			 * partition disk/fdisk calls ``dos''.
			 */
			if(havedos==0 && isdos(dp[i].type)){
				havedos = 1;
				sdaddpart(unit, "dos", start, end);
			}

			/* nxtxpart is relative to firstxpart (or 0), not taboffset */
			if(isextend(dp[i].type)){
				nxtxpart = start-taboffset+firstxpart;
				if(trace)
					print("link %lud...", nxtxpart);
			}
		}
		if(trace)
			print("\n");

		if(!nxtxpart)
			break;
		if(!firstxpart)
			firstxpart = nxtxpart;
		taboffset = nxtxpart;
	}
	return nplan9 ? 0 : -1;
}
Пример #10
0
static long
sdwrite(Chan* c, void* a, long n, vlong off)
{
	char *f0;
	int i;
	uvlong end, start;
	Cmdbuf *cb;
	SDifc *ifc;
	SDreq *req;
	SDunit *unit;
	SDev *sdev;

	switch(TYPE(c->qid)){
	default:
		error(Eperm);
	case Qtopctl:
		cb = parsecmd(a, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		if(cb->nf == 0)
			error("empty control message");
		f0 = cb->f[0];
		cb->f++;
		cb->nf--;
		if(strcmp(f0, "config") == 0){
			/* wormhole into ugly legacy interface */
			legacytopctl(cb);
			poperror();
			free(cb);
			break;
		}
		/*
		 * "ata arg..." invokes sdifc[i]->wtopctl(nil, cb),
		 * where sdifc[i]->name=="ata" and cb contains the args.
		 */
		ifc = nil;
		sdev = nil;
		for(i=0; sdifc[i]; i++){
			if(strcmp(sdifc[i]->name, f0) == 0){
				ifc = sdifc[i];
				sdev = nil;
				goto subtopctl;
			}
		}
		/*
		 * "sd1 arg..." invokes sdifc[i]->wtopctl(sdev, cb),
		 * where sdifc[i] and sdev match controller letter "1",
		 * and cb contains the args.
		 */
		if(f0[0]=='s' && f0[1]=='d' && f0[2] && f0[3] == 0){
			if((sdev = sdgetdev(f0[2])) != nil){
				ifc = sdev->ifc;
				goto subtopctl;
			}
		}
		error("unknown interface");

	subtopctl:
		if(waserror()){
			if(sdev)
				decref(&sdev->r);
			nexterror();
		}
		if(ifc->wtopctl)
			ifc->wtopctl(sdev, cb);
		else
			error(Ebadctl);
		poperror();
		poperror();
		if (sdev)
			decref(&sdev->r);
		free(cb);
		break;

	case Qctl:
		cb = parsecmd(a, n);
		sdev = sdgetdev(DEV(c->qid));
		if(sdev == nil)
			error(Enonexist);
		unit = sdev->unit[UNIT(c->qid)];

		qlock(&unit->ctl);
		if(waserror()){
			qunlock(&unit->ctl);
			decref(&sdev->r);
			free(cb);
			nexterror();
		}
		if(unit->vers != c->qid.vers)
			error(Echange);

		if(cb->nf < 1)
			error(Ebadctl);
		if(strcmp(cb->f[0], "part") == 0){
			if(cb->nf != 4)
				error(Ebadctl);
			if(unit->sectors == 0 && !sdinitpart(unit))
				error(Eio);
			start = strtoull(cb->f[2], 0, 0);
			end = strtoull(cb->f[3], 0, 0);
			sdaddpart(unit, cb->f[1], start, end);
		}
		else if(strcmp(cb->f[0], "delpart") == 0){
			if(cb->nf != 2 || unit->part == nil)
				error(Ebadctl);
			sddelpart(unit, cb->f[1]);
		}
		else if(unit->dev->ifc->wctl)
			unit->dev->ifc->wctl(unit, cb);
		else
			error(Ebadctl);
		qunlock(&unit->ctl);
		decref(&sdev->r);
		poperror();
		free(cb);
		break;

	case Qraw:
		sdev = sdgetdev(DEV(c->qid));
		if(sdev == nil)
			error(Enonexist);
		unit = sdev->unit[UNIT(c->qid)];
		qlock(&unit->raw);
		if(waserror()){
			qunlock(&unit->raw);
			decref(&sdev->r);
			nexterror();
		}
		switch(unit->state){
		case Rawcmd:
			if(n < 6 || n > sizeof(req->cmd))
				error(Ebadarg);
			if((req = malloc(sizeof(SDreq))) == nil)
				error(Enomem);
			req->unit = unit;
			memmove(req->cmd, a, n);
			req->clen = n;
			req->flags = SDnosense;
			req->status = ~0;

			unit->req = req;
			unit->state = Rawdata;
			break;

		case Rawstatus:
			unit->state = Rawcmd;
			free(unit->req);
			unit->req = nil;
			error(Ebadusefd);

		case Rawdata:
			unit->state = Rawstatus;
			unit->req->write = 1;
			n = sdrio(unit->req, a, n);
		}
		qunlock(&unit->raw);
		decref(&sdev->r);
		poperror();
		break;
	case Qpart:
		return sdbio(c, 1, a, n, off);
	}

	return n;
}