~kris/9p

9hist

052458ba28fcc4327434b2c9cff79a2e2b4cfbd8 — David du Colombier 35 years ago ebb118e
Plan 9 from Bell Labs 1991-07-28
2 files changed, 122 insertions(+), 40 deletions(-)

M pc/devfloppy.c
M pc/headland.c
M pc/devfloppy.c => pc/devfloppy.c +22 -20
@@ 29,15 29,10 @@ enum
	 Fwrite=	 0x47,	/* write cmd */
	 Fmulti=	 0x80,	/* or'd with Fread or Fwrite for multi-head */

	DMAmode0=	0xb,
	DMAmode1=	0xc,
	DMAaddr=	0x4,
	DMAtop=		0x81,
	DMAinit=	0xa,
	DMAcount=	0x5,

	Nfloppy=	4,	/* floppies/controller */

	DMAchan=	2,	/* floppy dma channel */

	/* sector size encodings */
	S128=		0,
	S256=		1,


@@ 48,6 43,11 @@ enum
	Drivemask=	3<<0,
	Seekend=	1<<5,
	Codemask=	(3<<6)|(3<<3),

	/* file types */
	Qdir=		0,
	Qdata=		16,
	Qstruct=	32,
};

/*


@@ 117,7 117,7 @@ struct Controller
	int	confused;
};

Controller	floppy[1];
Controller	floppy;

/*
 *  start a floppy drive's motor.  set an alarm for 1 second later to


@@ 151,8 151,6 @@ floppystop(Drive *dp)
{
	int cmd;

	if(!canqlock(dp))
		return;
	cmd = Fintena | Fena | dp->dev;
	outb(Fmotor, cmd);
	dp->motoron = 0;	


@@ 162,14 160,13 @@ floppykproc(Alarm* a)
{
	Drive *dp;

	if(waserror())
	for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){
		if(dp->motoron && TK2SEC(m->ticks - dp->lasttouched) > 5)
		if(dp->motoron && TK2SEC(m->ticks - dp->lasttouched) > 5
		&& canqlock(dp)){
			floppystop(dp);
			qunlock(dp);
		}
	}
		
	alarm(5*1000, floppyalarm, 0);
	cancel(a);
}

int


@@ 341,18 338,23 @@ floppyrecal(Drive *dp)
}

void
floppyinit(void)
floppyreset(void)
{
	Drive *dp;

	for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){
		dp->t = &floppytype[0];
		dp->cyl = -1;
		dp->dev = dp - floppy.d;
		dp->t = &floppytype[0];		/* default type */
		dp->motoron = 1;
		dp->cyl = -1;
		floppystop(dp);
	}
	setvec(22, floppyintr);
	alarm(5*1000, floppyalarm, (void *)0);
}

void
floppyinit(void)
{
	kproc(floppykproc, 0);
}

void

M pc/headland.c => pc/headland.c +100 -20
@@ 5,9 5,7 @@
#include	"fns.h"

/*
 *  headland hip set for the safari.
 *  
 *  serious magic!!!
 *  headland chip set for the safari.
 */

enum


@@ 18,10 16,24 @@ enum
};

/*
 *  ports used by the DMA controllers
 *  state of a dma transfer
 */
typedef struct DMA	DMA;
struct DMA {
typedef struct DMAxfer	DMAxfer;
struct DMAxfer
{
	Page	pg;		/* page used by dma */
	void	*va;		/* virtual address destination/src */
	long	len;		/* bytes to be transferred */
	int	isread;
};

/*
 *  the dma controllers.  the first half of this structure specifies
 *  the I/O ports used by the DMA controllers.
 */
typedef struct DMAport	DMAport;
struct DMAport
{
	uchar	addr[4];	/* current address (4 channels) */
	uchar	count[4];	/* current count (4 channels) */
	uchar	page[4];	/* page registers (4 channels) */


@@ 33,6 45,16 @@ struct DMA {
	uchar	mc;		/* master clear */
	uchar	cmask;		/* clear mask register */
	uchar	wam;		/* write all mask register bit */

	Lock;
};

typdef struct DMA	DMA;
struct DMA
{
	DMAport;
	Lock;
	DMAxfer	x[4];
};

DMA dma[2] = {


@@ 69,25 91,83 @@ exit(void)
}

/*
 *  setup a dma transfer.  return count actually set up.  we DMA up
 *  to a page.
 *  setup a dma transfer.  if the destination is not in kernel
 *  memory, allocate a page for the transfer.
 *
 *  we assume BIOS has set up the command register before we
 *  are booted.
 */
long
dmasetup(int d, int chan, Page *pg, long len, int isread)
dmasetup(int chan, void *va, long len, int isread)
{
	DMA *dp;
	ulong addr;
	DMAxfer *xp;
	ulong pa;
	uchar mode;

	dp = &dma[(chan>>2)&1];
	chan &= 3;
	xp = &dp->x[chan];

	dp = &dma[d];
	addr = (ulong)a;
	addr &= ~KZERO;
	/*
	 *  if this isn't kernel memory, we can't count on it being
	 *  there during the DMA.  Allocate a page for the DMA.
	 */
	if(isphys(va)){
		pa = va & ~KZERO;
	} else {
		xp->pg = newpage(1, 0, 0);
		if(len > BY2PG)
			len = BY2PG;
		if(!isread)
			memmove(KZERO|xp->pg->pa, a, len);
		xp->va = va;
		xp->len = len;
		xp->isread = isread;
		pa = xp->pg->pa;
	}

	outb(dp->cbp, isread ? 0x46 : 0x4a);
	outb(dp->mode, isread ? 0x46 : 0x4a);
	outb(dp->addr, addr);
	outb(dp->addr, addr>>8);
	outb(dp->page, addr>>16);
	outb(dp->count, len-1);
	/*
	 * this setup must be atomic
	 */
	lock(dp);
	outb(dp->cbp, 0);		/* set count & address to their first byte */
	mode = (isread ? 0x44 : 0x48) | chan;
	outb(dp->mode, mode);		/* single mode dma (give CPU a chance at mem) */
	outb(dp->addr, pa);		/* set address */
	outb(dp->addr, pa>>8);
	outb(dp->page, pa>>16);
	outb(dp->count, len-1);		/* set count */
	outb(dp->count, (len-1)>>8);
	outb(dp->sbm, 2);
	outb(dp->sbm, chan);		/* enable the channel */
	unlock(dp);

	return n;
}

/*
 *  this must be called after a dma has been completed.
 *
 *  if a page has been allocated for the dma,
 *  copy the data into the actual destination
 *  and free the page.
 */
void
dmaend(int chan)
{
	DMA *dp;
	DMAxfer *xp;
	ulong addr;
	uchar mode;

	dp = &dma[(chan>>2)&1];
	chan &= 3;
	outb(dp->sbm, 4|chan);		/* disable the channel */
	xp = &dp->x[chan];
	if(xp->pg == 0)
		return;

	memmove(a, KZERO|xp->pg->pa, xp->len);
	putpage(xp->pg);
	xp->pg = 0;
}