4.3BSD-UWisc/src/sys/vaxuba/ad.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Copyright (c) 1982, 1986 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 *
 *	@(#)ad.c	7.1 (Berkeley) 6/5/86
 */
#ifndef lint
static char rcs_id[] = {"$Header: ad.c,v 3.1 86/10/22 14:01:48 tadl Exp $"};
#endif not lint
/*
 * RCS Info
 *	$Locker:  $
 */

#include "ad.h"
#if NAD > 0
/*
 * Data translation AD converter interface -- Bill Reeves
 */
#include "../machine/pte.h"

#include "param.h"
#include "dir.h"
#include "user.h"
#include "buf.h"
#include "systm.h"
#include "map.h"

#include "ubareg.h"
#include "ubavar.h"
#include "adreg.h"

#define ADBUSY 01
#define ADWAITPRI (PZERO+1)

int adprobe(), adattach();
struct uba_device *addinfo[NAD];
u_short adstd[] = { 0770400, 0000000, 0 };
struct uba_driver addriver =
	{ adprobe, 0, adattach, 0, adstd, "ad", addinfo, 0, 0 };

struct ad {
	char	ad_open;
	short int ad_uid;
	short int ad_state;
	short int ad_softcsr;
	short int ad_softdata;
	short int ad_chan;
	int	ad_icnt;
	int	ad_loop;
} ad[NAD];

#define ADUNIT(dev) (minor(dev))

adprobe(reg)
	caddr_t reg;
{
	register int br, cvec;		/* value-result */
	register struct addevice *adaddr = (struct addevice *) reg;

	adaddr->ad_csr = AD_IENABLE | AD_START;
	DELAY(40000);
	adaddr->ad_csr = 0;
	return (sizeof (struct addevice));
}

/*ARGSUSED*/
adattach(ui)
	struct uba_device *ui;
{

}

adopen(dev)
	dev_t dev;
{
	register struct ad *adp;
	register struct uba_device *ui;

	if (ADUNIT(dev) >= NAD || (adp = &ad[ADUNIT(dev)])->ad_open ||
	    (ui = addinfo[ADUNIT(dev)]) == 0 || ui->ui_alive == 0)
		return (ENXIO);
	adp->ad_open = 1;
	adp->ad_icnt = 0;
	adp->ad_state = 0;
	adp->ad_uid = u.u_uid;
	return (0);
}

adclose(dev)
	dev_t dev;
{

	ad[ADUNIT(dev)].ad_open = 0;
	ad[ADUNIT(dev)].ad_state = 0;
}

/*ARGSUSED*/
adioctl(dev, cmd, addr, flag)
	dev_t dev;
	register caddr_t addr;
{
	register struct addevice *adaddr =
	    (struct addevice *) addinfo[ADUNIT(dev)]->ui_addr;
	register struct uba_device *ui = addinfo[ADUNIT(dev)];
	register struct ad *adp;
	register int i;
	short int chan;

	switch (cmd) {

	case ADIOSCHAN:
		adp = &ad[ADUNIT(dev)];
		adp->ad_chan = (*(int *)data)<<8;
		break;

	case ADIOGETW:
		adp = &ad[ADUNIT(dev)];
		spl6();
		adaddr->ad_csr = adp->ad_chan;
		i = 1000;
		while (i-- > 0 && (adaddr->ad_csr&037400) != adp->ad_chan) {
			adp->ad_loop++;
			adaddr->ad_csr = adp->ad_chan;
		}
		adp->ad_state |= ADBUSY;
		adaddr->ad_csr |= AD_IENABLE|AD_START;
		while (adp->ad_state&ADBUSY)
			sleep((caddr_t)adp, ADWAITPRI);
		spl0();
		*(int *)data = adp->ad_softdata;
		break;

	default:
		return (ENOTTY);	/* Not a legal ioctl cmd. */
	}
	return (0);
}

/*ARGSUSED*/
adintr(dev)
	dev_t dev;
{
	register struct addevice *adaddr =
			(struct addevice *) addinfo[ADUNIT(dev)]->ui_addr;
	register struct ad *adp = &ad[ADUNIT(dev)];

	adp->ad_icnt++;
	adp->ad_softcsr = adaddr->ad_csr;
	adp->ad_softdata = adaddr->ad_data;
	if(adp->ad_state&ADBUSY) {
		adp->ad_state &= ~ADBUSY;
		wakeup((caddr_t)adp);
	}
}

adreset(uban)
	int uban;
{
	register int i;
	register struct uba_device *ui;
	register struct ad *adp = ad;
	register struct addevice *adaddr;

	for(i = 0; i < NAD; i++, adp++) {
		if((ui = addinfo[i]) == 0 || ui->ui_alive == 0 ||
				ui->ui_ubanum != uban || adp->ad_open == 0)
			continue;
		printf(" ad%d", i);
		if(adp->ad_state&ADBUSY == 0)
			continue;
		adaddr = (struct addevice *) ui->ui_addr;
		adaddr->ad_csr = 0;
		adaddr->ad_csr = adp->ad_chan|AD_IENABLE|AD_START;
	}
}
#endif