~kris/9p

9hist

4836e8f92c46890b969127b09b8a7e30877266ca — David du Colombier 33 years ago b06eb0a
Plan 9 from Bell Labs 1992-10-09
6 files changed, 123 insertions(+), 72 deletions(-)

M pc/devfloppy.c
M port/devcons.c
M port/devscsi.c
M port/devwren.c
M port/portdat.h
M port/portfns.h
M pc/devfloppy.c => pc/devfloppy.c +95 -71
@@ 5,6 5,7 @@
#include	"fns.h"
#include	"io.h"
#include	"../port/error.h"
#include	"devtab.h"

/* Intel 82077A (8272A compatible) floppy controller */



@@ 194,7 195,7 @@ static long	floppyseek(Drive*, long);
static int	floppysense(void);
static void	floppywait(void);
static long	floppyxfer(Drive*, int, void*, long, long);
static int	floppyformat(Drive*, ulong, ulong);
static void	floppyformat(Drive*, char*);
static long	floppythrice(Drive*, int, void*, long, long);
static int	cmddone(void*);
void Xdelay(int);


@@ 362,9 363,9 @@ floppywstat(Chan *c, char *dp)
}

static void
islegal(Chan *c, long n, Drive *dp)
islegal(ulong offset, long n, Drive *dp)
{
	if(c->offset % dp->t->bytes)
	if(offset % dp->t->bytes)
		error(Ebadarg);
	if(n % dp->t->bytes)
		error(Ebadarg);


@@ 400,7 401,7 @@ changed(Chan *c, Drive *dp)
}

long
floppyread(Chan *c, void *a, long n)
floppyread(Chan *c, void *a, long n, ulong offset)
{
	Drive *dp;
	long rv, i;


@@ 415,7 416,7 @@ floppyread(Chan *c, void *a, long n)
	dp = &fl.d[c->qid.path & ~Qmask];
	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		islegal(c, n, dp);
		islegal(offset, n, dp);
		aa = a;

		qlock(&fl);


@@ 430,7 431,7 @@ floppyread(Chan *c, void *a, long n)
			 *  truncate xfer at track boundary
			 */
			dp->len = n - rv;
			floppypos(dp, c->offset+rv);
			floppypos(dp, offset+rv);
			cyl = dp->tcyl;
			head = dp->thead;
			len = dp->len;


@@ 470,19 471,18 @@ floppyread(Chan *c, void *a, long n)

#define SNCMP(a, b) strncmp(a, b, sizeof(b)-1)
long
floppywrite(Chan *c, void *a, long n)
floppywrite(Chan *c, void *a, long n, ulong offset)
{
	Drive *dp;
	long rv, i;
	char *aa = a;
	char *f[3];
	char ctlmsg[64];

	rv = 0;
	dp = &fl.d[c->qid.path & ~Qmask];
	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		islegal(c, n, dp);
		islegal(offset, n, dp);
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);


@@ 491,10 491,10 @@ floppywrite(Chan *c, void *a, long n)
		floppyon(dp);
		changed(c, dp);
		for(rv = 0; rv < n; rv += i){
			floppypos(dp, c->offset+rv);
			floppypos(dp, offset+rv);
			if(dp->tcyl == dp->ccyl)
				dp->ccyl = -1;
			i = floppythrice(dp, Fwrite, aa+rv, c->offset+rv, n-rv);
			i = floppythrice(dp, Fwrite, aa+rv, offset+rv, n-rv);
			if(i < 0)
				break;
			if(i == 0)


@@ 504,6 504,7 @@ floppywrite(Chan *c, void *a, long n)
		poperror();
		break;
	case Qctl:
		rv = n;
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);


@@ 519,9 520,7 @@ floppywrite(Chan *c, void *a, long n)
			fl.confused = 1;
			floppyon(dp);
		} else if(SNCMP(ctlmsg, "format") == 0){
			if(getfields(ctlmsg, f, 3, ' ') != 3)
				error(Ebadarg);
			rv = n*floppyformat(dp, strtoul(f[1], 0, 0), strtoul(f[2], 0, 0));
			floppyformat(dp, ctlmsg);
		}
		poperror();
		qunlock(&fl);


@@ 956,82 955,107 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n)
/*
 *  format a track
 */
static int
floppyformat(Drive *dp, ulong track, ulong filler)
static void
floppyformat(Drive *dp, char *params)
{
 	int cyl, h, sec;
	ulong track;
	uchar *buf, *bp;
	Type *t;

	t = dp->t;
	cyl = track/t->heads;
	h = track % t->heads;
	if(track >= t->tracks * t->heads)
		return 0;
	setdef(dp);
	buf = smalloc(t->sectors*4);
	if(waserror()){
		free(buf);
		nexterror();
	}
	if(!waserror()){
		floppyon(dp);
		poperror();
	}
	floppyseek(dp, track*t->tsize);
	dp->cyl = cyl;
	dp->confused = 0;
	char *f[3];

	/*
	 *  set up the dma (dp->len may be trimmed)
	 *  set the type
	 */
	bp = buf;
	for(sec = 1; sec <= t->sectors; sec++){
		*bp++ = cyl;
		*bp++ = h;
		*bp++ = sec;
		*bp++ = t->bcode;
	if(getfields(params, f, 3, ' ') > 1){
		for(t = floppytype; t < &floppytype[NTYPES]; t++)
			if(strcmp(f[1], t->name)==0 && t->dt==dp->dt){
				dp->t = t;
				floppydir[NFDIR*dp->dev].length = dp->t->cap;
				break;
			}
	} else {
		setdef(dp);
		t = dp->t;
	}
	dmasetup(DMAchan, buf, bp-buf, 0);

	/*
	 *  start operation
	 *  buffer for per track info
	 */
	fl.ncmd = 0;
	fl.cmd[fl.ncmd++] = Fformat;
	fl.cmd[fl.ncmd++] = (h<<2) | dp->dev;
	fl.cmd[fl.ncmd++] = t->bcode;
	fl.cmd[fl.ncmd++] = t->sectors;
	fl.cmd[fl.ncmd++] = t->fgpl;
	fl.cmd[fl.ncmd++] = filler;
	if(floppycmd() < 0){
		DPRINT("xfer cmd failed\n");
		error(Eio);
	buf = smalloc(t->sectors*4);
	if(waserror()){
		free(buf);
		nexterror();
	}

	/*
	 *  give bus to DMA, floppyintr() will read result
	 *  format a track at time
	 */
	floppywait();
	dmaend(DMAchan);
	for(track = 0; track < t->tracks*t->heads; track++){
		cyl = track/t->heads;
		h = track % t->heads;

	/*
	 *  check for errors
	 */
	if(fl.nstat < 7){
		DPRINT("format result failed %lux\n", inb(Pmsr));
		fl.confused = 1;
		error(Eio);
	}
	if((fl.stat[0]&Codemask)!=0 || fl.stat[1] || fl.stat[2]){
		DPRINT("format failed %lux %lux %lux\n",
			fl.stat[0], fl.stat[1], fl.stat[2]);
		dp->confused = 1;
		error(Eio);
		/*
		 *  seek to track, ignore errors
		 */
		if(!waserror()){
			floppyon(dp);
			poperror();
		}
		floppyseek(dp, track*t->tsize);
		dp->cyl = cyl;
		dp->confused = 0;

		/*
		 *  set up the dma (dp->len may be trimmed)
		 */
		bp = buf;
		for(sec = 1; sec <= t->sectors; sec++){
			*bp++ = cyl;
			*bp++ = h;
			*bp++ = sec;
			*bp++ = t->bcode;
		}
		dmasetup(DMAchan, buf, bp-buf, 0);

		/*
		 *  start operation
		 */
		fl.ncmd = 0;
		fl.cmd[fl.ncmd++] = Fformat;
		fl.cmd[fl.ncmd++] = (h<<2) | dp->dev;
		fl.cmd[fl.ncmd++] = t->bcode;
		fl.cmd[fl.ncmd++] = t->sectors;
		fl.cmd[fl.ncmd++] = t->fgpl;
		fl.cmd[fl.ncmd++] = 0x5a;
		if(floppycmd() < 0){
			DPRINT("xfer cmd failed\n");
			error(Eio);
		}

		/*
		 *  give bus to DMA, floppyintr() will read result
		 */
		floppywait();
		dmaend(DMAchan);

		/*
		 *  check for errors
		 */
		if(fl.nstat < 7){
			DPRINT("format result failed %lux\n",inb(Pmsr));
			fl.confused = 1;
			error(Eio);
		}
		if((fl.stat[0]&Codemask)!=0 || fl.stat[1]|| fl.stat[2]){
			DPRINT("format failed %lux %lux %lux\n",
				fl.stat[0], fl.stat[1], fl.stat[2]);
			dp->confused = 1;
			error(Eio);
		}
	}
	free(buf);
	poperror();
	return 1;
}

static void

M port/devcons.c => port/devcons.c +0 -1
@@ 837,7 837,6 @@ conswrite(Chan *c, void *va, long n, ulong offset)
			memmove(u->p->user, buf, NAMELEN);
		else
			error(Eperm);
		memset(u->p->pgrp->crypt->key, 0, DESKEYLEN);
		if(!cpuserver && strcmp(eve, "bootes")==0)
			memmove(eve, u->p->user, NAMELEN);
		break;

M port/devscsi.c => port/devscsi.c +24 -0
@@ 324,6 324,9 @@ scsicmd(int dev, int cmdbyte, Scsibuf *b, long size)
	switch(cmdbyte){
	case ScsiTestunit:
		break;
	case ScsiStartunit:
		cmd->cmdblk[4] = 1;
		break;
	case ScsiModesense:
		cmd->cmdblk[2] = 1;
		/* fall through */


@@ 364,6 367,27 @@ scsiready(int dev)
}

int
scsistartstop(int dev, int cmdbyte)
{
	Scsi *cmd;
	int status;

	cmd = scsicmd(dev, cmdbyte, scsibuf(), 0);
	if(waserror()){
		scsifree(cmd->b);
		qunlock(cmd);
		nexterror();
	}
	status = scsiexec(cmd, ScsiOut);
	poperror();
	scsifree(cmd->b);
	qunlock(cmd);
	if((status&0xff00) != 0x6000)
		error(Eio);
	return status&0xff;
}

int
scsisense(int dev, void *p)
{
	Scsi *cmd;

M port/devwren.c => port/devwren.c +1 -0
@@ 275,6 275,7 @@ wrenpart(int dev)
	qlock(dp);
	scsiready(dev);
	scsisense(dev, buf);
	scsistartstop(dev, ScsiStartunit);
	if(scsicap(dev, buf))
		error(Eio);
	dp->drive = dev;

M port/portdat.h => port/portdat.h +2 -0
@@ 230,6 230,8 @@ enum
	ScsiExtsens	= 0x03,
	ScsiInquiry	= 0x12,
	ScsiModesense	= 0x1a,
	ScsiStartunit	= 0x1B,
	ScsiStopunit	= 0x1B,
	ScsiGetcap	= 0x25,
	ScsiRead	= 0x08,
	ScsiWrite	= 0x0a,

M port/portfns.h => port/portfns.h +1 -0
@@ 208,6 208,7 @@ void		scsifree(Scsibuf*);
int		scsiinquiry(int, void*, int);
int		scsimodesense(int, int, void*, int);
int		scsiready(int);
int		scsistartstop(int, int);
int		scsisense(int, void*);
int		scsiwp(int);
long		seconds(void);