⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devsd.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	if(sdev == nil || sdgetunit(sdev, subno) == nil)		error(Enonexist);	c = devattach(sddevtab.dc, spec);	c->qid = (Qid){QID(sdev->index+subno, 0, Qunitdir)|CHDIR, 0};	c->dev = sdev->index+subno;	return c;}static Chan*sdclone(Chan* c, Chan* nc){	return devclone(c, nc);}static intsdwalk(Chan* c, char* name){	return devwalk(c, name, nil, 0, sdgen);}static voidsdstat(Chan* c, char* db){	devstat(c, db, nil, 0, sdgen);}static Chan*sdopen(Chan* c, int omode){	SDpart *pp;	SDunit *unit;	c = devopen(c, omode, 0, 0, sdgen);	switch(TYPE(c->qid)){	default:		break;	case Qraw:		unit = sdunit[UNIT(c->qid)];		if(!canlock(&unit->rawinuse)){			c->flag &= ~COPEN;			error(Einuse);		}		unit->state = Rawcmd;		break;	case Qpart:		unit = sdunit[UNIT(c->qid)];		qlock(&unit->ctl);		if(waserror()){			qunlock(&unit->ctl);			c->flag &= ~COPEN;			nexterror();		}		if(unit->changed)			error(Eio);		pp = &unit->part[PART(c->qid)];		pp->nopen++;		unit->nopen++;		qunlock(&unit->ctl);		poperror();		break;	}	return c;}static voidsdclose(Chan* c){	SDpart *pp;	SDunit *unit;	if(c->qid.path & CHDIR)		return;	if(!(c->flag & COPEN))		return;	switch(TYPE(c->qid)){	default:		break;	case Qraw:		unit = sdunit[UNIT(c->qid)];		unlock(&unit->rawinuse);		break;	case Qpart:		unit = sdunit[UNIT(c->qid)];		qlock(&unit->ctl);		if(waserror()){			qunlock(&unit->ctl);			c->flag &= ~COPEN;			nexterror();		}		pp = &unit->part[PART(c->qid)];		pp->nopen--;		unit->nopen--;		if(unit->nopen == 0)			unit->changed = 0;		qunlock(&unit->ctl);		poperror();		break;	}}static longsdbio(Chan* c, int write, char* a, long len, vlong off){	long l;	uchar *b;	SDpart *pp;	SDunit *unit;	ulong bno, max, nb, offset;	unit = sdunit[UNIT(c->qid)];	qlock(&unit->ctl);	if(waserror()){		qunlock(&unit->ctl);		nexterror();	}	if(unit->changed)		error(Eio);	/*	 * Check the request is within bounds.	 * Removeable drives are locked throughout the I/O	 * in case the media changes unexpectedly.	 * Non-removeable drives are not locked during the I/O	 * to allow the hardware to optimise if it can; this is	 * a little fast and loose.	 * It's assumed that non-removeable media parameters	 * (sectors, secsize) can't change once the drive has	 * been brought online.	 */	pp = &unit->part[PART(c->qid)];	bno = (off/unit->secsize) + pp->start;	nb = ((off+len+unit->secsize-1)/unit->secsize) + pp->start - bno;	max = SDmaxio/unit->secsize;	if(nb > max)		nb = max;	if(bno+nb > pp->end)		nb = pp->end - bno;	if(bno >= pp->end || nb == 0){		if(write)			error(Eio);		qunlock(&unit->ctl);		poperror();		return 0;	}	if(!(unit->inquiry[1] & 0x80)){		qunlock(&unit->ctl);		poperror();	}	b = sdmalloc(nb*unit->secsize);	if(b == nil)		error(Enomem);	if(waserror()){		sdfree(b);		nexterror();	}	offset = off%unit->secsize;	if(write){		if(offset || (len%unit->secsize)){			l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);			if(l < 0)				error(Eio);			if(l < (nb*unit->secsize)){				nb = l/unit->secsize;				l = nb*unit->secsize - offset;				if(len > l)					len = l;			}		}		memmove(b+offset, a, len);		l = unit->dev->ifc->bio(unit, 0, 1, b, nb, bno);		if(l < 0)			error(Eio);		if(l < offset)			len = 0;		else if(len > l - offset)			len = l - offset;	}	else {		l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);		if(l < 0)			error(Eio);		if(l < offset)			len = 0;		else if(len > l - offset)			len = l - offset;		memmove(a, b+offset, len);	}	sdfree(b);	poperror();	if(unit->inquiry[1] & 0x80){		qunlock(&unit->ctl);		poperror();	}	return len;}static longsdrio(SDreq* r, void* a, long n){	void *data;	if(n >= SDmaxio || n < 0)		error(Etoobig);	data = nil;	if(n){		if((data = sdmalloc(n)) == nil)			error(Enomem);		if(r->write)			memmove(data, a, n);	}	r->data = data;	r->dlen = n;	if(waserror()){		if(data != nil){			sdfree(data);			r->data = nil;		}		nexterror();	}	if(r->unit->dev->ifc->rio(r) != SDok)		error(Eio);	if(!r->write && r->rlen > 0)		memmove(a, data, r->rlen);	if(data != nil){		sdfree(data);		r->data = nil;	}	poperror();	return r->rlen;}static longsdread(Chan *c, void *a, long n, vlong off){	char *p;	SDpart *pp;	SDunit *unit;	ulong offset;	int i, l, status;	offset = off;	switch(TYPE(c->qid)){	default:		error(Eperm);	case Qtopdir:	case Qunitdir:		return devdirread(c, a, n, 0, 0, sdgen);	case Qctl:		unit = sdunit[UNIT(c->qid)];		p = malloc(READSTR);		l = snprint(p, READSTR, "inquiry %.48s\n",			(char*)unit->inquiry+8);		qlock(&unit->ctl);		/*		 * If there's a device specific routine it must		 * provide all information pertaining to night geometry		 * and the garscadden trains.		 */		if(unit->dev->ifc->rctl)			l += unit->dev->ifc->rctl(unit, p+l, READSTR-l);		if(!unit->changed && unit->sectors){			if(unit->dev->ifc->rctl == nil)				l += snprint(p+l, READSTR-l,					"geometry %ld %ld\n",					unit->sectors, unit->secsize);			pp = unit->part;			for(i = 0; i < SDnpart; i++){				if(pp->valid)					l += snprint(p+l, READSTR-l,						"part %.*s %lud %lud\n",						NAMELEN, pp->name,						pp->start, pp->end);				pp++;			}		}		qunlock(&unit->ctl);		l = readstr(offset, a, n, p);		free(p);		return l;	case Qraw:		unit = sdunit[UNIT(c->qid)];		if(unit->state == Rawdata){			unit->state = Rawstatus;			return sdrio(unit->req, a, n);		}		else if(unit->state == Rawstatus){			status = unit->req->status;			unit->state = Rawcmd;			free(unit->req);			unit->req = nil;			return readnum(0, a, n, status, NUMSIZE);		}		break;	case Qpart:		return sdbio(c, 0, a, n, off);	}	return 0;}static longsdwrite(Chan *c, void *a, long n, vlong off){	Cmdbuf *cb;	SDreq *req;	SDunit *unit;	ulong end, start;	switch(TYPE(c->qid)){	default:		error(Eperm);	case Qctl:		cb = parsecmd(a, n);		unit = sdunit[UNIT(c->qid)];		qlock(&unit->ctl);		if(waserror()){			qunlock(&unit->ctl);			free(cb);			nexterror();		}		if(unit->changed)			error(Eio);		if(cb->nf < 1)			error(Ebadctl);		if(strcmp(cb->f[0], "part") == 0){			if(cb->nf != 4 || unit->npart >= SDnpart)				error(Ebadctl);			if(unit->sectors == 0 && !sdinitpart(unit))				error(Eio);			start = strtoul(cb->f[2], 0, 0);			end = strtoul(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);		poperror();		free(cb);		break;	case Qraw:		unit = sdunit[UNIT(c->qid)];		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:			if(unit->state != Rawdata)				error(Ebadusefd);			unit->state = Rawstatus;			unit->req->write = 1;			return sdrio(unit->req, a, n);		}		break;	case Qpart:		return sdbio(c, 1, a, n, off);	}	return n;}static voidsdwstat(Chan* c, char* dp){	Dir d;	SDpart *pp;	SDunit *unit;	if((c->qid.path & CHDIR) || TYPE(c->qid) != Qpart)		error(Eperm);	unit = sdunit[UNIT(c->qid)];	qlock(&unit->ctl);	if(waserror()){		qunlock(&unit->ctl);		nexterror();	}	if(unit->changed)		error(Enonexist);	pp = &unit->part[PART(c->qid)];	if(!pp->valid)		error(Enonexist);	if(strncmp(up->user, pp->user, NAMELEN) && !iseve())		error(Eperm);	convM2D(dp, &d);	strncpy(pp->user, d.uid, NAMELEN);	pp->perm = d.mode&0777;	qunlock(&unit->ctl);	poperror();}Dev sddevtab = {	'S',	"sd",	sdreset,	devinit,	sdattach,	sdclone,	sdwalk,	sdstat,	sdopen,	devcreate,	sdclose,	sdread,	devbread,	sdwrite,	devbwrite,	devremove,	sdwstat,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -