xref: /original-bsd/sys/vax/uba/ps.c (revision 7b081c7c)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)ps.c	7.4 (Berkeley) 02/17/90
7  */
8 
9 /*
10  * Evans and Sutherland Picture System 2 driver -- Bill Reeves.
11  */
12 
13 /*
14  *	Still to be done:
15  *		WAIT_HIT
16  */
17 
18 #include "ps.h"
19 #if NPS > 0
20 
21 #define EXTERNAL_SYNC
22 
23 #include "machine/pte.h"
24 
25 #include "param.h"
26 #include "systm.h"
27 #include "ioctl.h"
28 #include "map.h"
29 #include "buf.h"
30 #include "conf.h"
31 #include "user.h"
32 #include "uio.h"
33 #include "tsleep.h"
34 
35 #include "ubareg.h"
36 #include "ubavar.h"
37 #include "psreg.h"
38 
39 int	psprobe(), psattach(), psextsync();
40 int	psclockintr(), pssystemintr(), psdeviceintr(), psdmaintr();
41 struct	uba_device *psdinfo[NPS];
42 u_short	psstd[] = { 0 };
43 struct	uba_driver psdriver =
44     { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };
45 
46 #define	PSUNIT(dev)	(minor(dev))
47 
48 #define MAXAUTOREFRESH	4
49 #define MAXAUTOMAP	4
50 #define MAXDBSIZE	(0177777/2)
51 
52 #define PSPRI		(PZERO+1)
53 
54 #define PSWAIT(psaddr) { \
55 	register short i = 20000, j; \
56 	while (i-- != 0 && ((j = psaddr->ps_iostat) & DIOREADY) == 0) \
57 		;\
58 }
59 
60 struct psrefresh {
61 	enum {
62 		SINGLE_STEP_RF,
63 		AUTO_RF,
64 		TIME_RF
65 	} state;
66 	enum {
67 		RUNNING_RF,
68 		SYNCING_RF,
69 		WAITING_MAP,
70 		STOPPED_RF
71 	} mode;
72 	u_short	sraddrs[MAXAUTOREFRESH];
73 	short	nsraddrs;
74 	short	srcntr;
75 	char	waiting;
76 	char	stop;
77 	int	icnt;
78 	int	timecnt;
79 };
80 
81 struct psdbuffer {
82 	enum {
83 		ON_DB,
84 		OFF_DB
85 	} state;
86 	u_short	dbaddrs[2];
87 	u_short	dbsize;
88 	short	rbuffer;
89 };
90 
91 struct psmap {
92 	enum {
93 		SINGLE_STEP_MAP,
94 		AUTO_MAP
95 	} state;
96 	enum {
97 		RUNNING_MAP,
98 		WAITING_RF,
99 		WAITING_START,
100 		STOPPED_MAP
101 	} mode;
102 	u_short	maddrs[MAXAUTOMAP];
103 	short	nmaddrs;
104 	short	mcntr;
105 	short	outputstart;
106 	char	waiting;
107 	char	stop;
108 	int	icnt;
109 };
110 
111 /*
112  * PS2 software state.
113  */
114 struct ps {
115 	char	ps_open;		/* device is open */
116 	uid_t 	ps_uid;			/* uid of device owner */
117 	struct	psrefresh ps_refresh;	/* refresh state */
118 	struct	psdbuffer ps_dbuffer;	/* double buffering state */
119 	struct	psmap ps_map;		/* segment map state */
120 	int	ps_clockticks;		/* clock ints between refresh */
121 	int	ps_clockmiss;		/* clock ints w/o refresh */
122 	int	ps_clockcnt;		/* count of clock interrupts */
123 	int	ps_hitcnt;		/* count of hit interrupts */
124 	int	ps_strayintr;		/* count of stray interrupts */
125 	int	ps_icnt;		/* count of system interrupts */
126 /* BEGIN GROT */
127 	int	ps_lastrequest;
128 	int	ps_lastrequest2;
129 	int	ps_lastfunnyrequest;
130 	int	ps_funnycnt;
131 /* END GROT */
132 } ps[NPS];
133 
134 psprobe(reg)
135 	caddr_t reg;
136 {
137 	register int br, cvec;
138 	register struct psdevice *psaddr = (struct psdevice *)reg;
139 
140 #ifdef lint
141 	br = 0; cvec = br; br = cvec;
142 	psclockintr((dev_t)0); pssystemintr((dev_t)0);
143 	psdeviceintr((dev_t)0); psdmaintr((dev_t)0);
144 	psextsync(0, 0);
145 #endif
146 	psaddr->ps_iostat = PSRESET;
147 	DELAY(200);
148 	psaddr->ps_addr = RTCIE;
149 	PSWAIT(psaddr); psaddr->ps_data = 01;
150 	psaddr->ps_iostat = PSIE;
151 	psaddr->ps_addr = RTCSR;
152 	PSWAIT(psaddr); psaddr->ps_data = SYNC|RUN;
153 	DELAY(200000);
154 	psaddr->ps_addr = RTCREQ;
155 	PSWAIT(psaddr); psaddr->ps_data = 01;
156 	psaddr->ps_iostat = 0;
157 	psaddr->ps_iostat = PSRESET;
158 	return (sizeof (struct psdevice));
159 }
160 
161 /*ARGSUSED*/
162 psattach(ui)
163 	struct uba_device *ui;
164 {
165 
166 }
167 
168 psopen(dev)
169 	dev_t dev;
170 {
171 	register struct ps *psp;
172 	register struct uba_device *ui;
173 	register int unit = PSUNIT(dev);
174 
175 	if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||
176 	    (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0)
177 		return (ENXIO);
178 	psp->ps_open = 1;
179 	psp->ps_uid = u.u_uid;
180 	psp->ps_strayintr = 0;
181 	psp->ps_refresh.state = SINGLE_STEP_RF;
182 	psp->ps_refresh.mode = STOPPED_RF;
183 	psp->ps_refresh.waiting = 0;
184 	psp->ps_refresh.stop = 0;
185 	psp->ps_dbuffer.state = OFF_DB;
186 	psp->ps_map.state = SINGLE_STEP_MAP;
187 	psp->ps_map.mode = STOPPED_MAP;
188 	psp->ps_map.waiting = 0;
189 	psp->ps_map.stop = 0;
190 	psp->ps_clockticks = 0;
191 	psp->ps_clockmiss = 0;
192 	psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clockcnt = 0;
193 	psp->ps_hitcnt = 0;
194 	psp->ps_icnt = 0;
195 	maptouser(ui->ui_addr);
196 	return (0);
197 }
198 
199 psclose(dev)
200 	dev_t dev;
201 {
202 	register struct psdevice *psaddr =
203 	    (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
204 
205 	ps[PSUNIT(dev)].ps_open = 0;
206 	psaddr->ps_iostat = 0;			 /* clear IENABLE */
207 	PSWAIT(psaddr); psaddr->ps_addr = RFSR;	 /* set in auto refresh mode */
208 	PSWAIT(psaddr); psaddr->ps_data = AUTOREF;
209 	unmaptouser((caddr_t)psaddr);
210 }
211 
212 /*ARGSUSED*/
213 psread(dev, uio)
214 	dev_t dev;
215 	struct uio *uio;
216 {
217 }
218 
219 /*ARGSUSED*/
220 pswrite(dev, uio)
221 	dev_t dev;
222 	struct uio *uio;
223 {
224 }
225 
226 /*ARGSUSED*/
227 psioctl(dev, cmd, data, flag)
228 	register caddr_t data;
229 {
230 	register struct uba_device *ui = psdinfo[PSUNIT(dev)];
231 	register struct ps *psp = &ps[PSUNIT(dev)];
232 	int *waddr = *(int **)data;
233 	int n, arg, i;
234 
235 	switch (cmd) {
236 
237 	case PSIOGETADDR:
238 		*(caddr_t *)data = ui->ui_addr;
239 		break;
240 
241 	case PSIOAUTOREFRESH:
242 		n = fuword((caddr_t)waddr++);
243 		if (n == -1)
244 			return (EFAULT);
245 		if (n < 0 || n > MAXAUTOREFRESH)
246 			return (EINVAL);
247 		for (i = 0; i < n; i++) {
248 			if ((arg = fuword((caddr_t)waddr++)) == -1)
249 				return (EFAULT);
250 			psp->ps_refresh.sraddrs[i] = arg;
251 		}
252 		psp->ps_refresh.state = AUTO_RF;
253 		psp->ps_refresh.nsraddrs = n;
254 		psp->ps_refresh.srcntr = 0;
255 		psp->ps_refresh.mode = WAITING_MAP;
256 		break;
257 
258 	case PSIOAUTOMAP:
259 		n = fuword((caddr_t)waddr++);
260 		if (n == -1)
261 			return (EFAULT);
262 		if (n < 0 || n > MAXAUTOMAP)
263 			return (EINVAL);
264 		for (i = 0; i < n; i++) {
265 			if ((arg = fuword((caddr_t)waddr++)) == -1)
266 				return (EFAULT);
267 			psp->ps_map.maddrs[i] = arg;
268 		}
269 		if ((arg = fuword((caddr_t)waddr++)) == -1)
270 			return (EFAULT);
271 		psp->ps_map.outputstart = arg;
272 		psp->ps_map.state = AUTO_MAP;
273 		psp->ps_map.nmaddrs = n;
274 		psp->ps_map.mcntr = 0;
275 		psp->ps_map.mode = WAITING_START;
276 		break;
277 
278 	case PSIOSINGLEREFRESH:
279 		psp->ps_refresh.state = SINGLE_STEP_RF;
280 		break;
281 
282 	case PSIOSINGLEMAP:
283 		psp->ps_map.state = SINGLE_STEP_MAP;
284 		break;
285 
286 	case PSIODOUBLEBUFFER:
287 		if ((arg = fuword((caddr_t)waddr++)) == -1)
288 			return (EFAULT);
289 		psp->ps_dbuffer.dbaddrs[0] = arg;
290 		if ((arg = fuword((caddr_t)waddr++)) == -1)
291 			return (EFAULT);
292 		if (arg <= 0 || arg > MAXDBSIZE)
293 			return (EINVAL);
294 		psp->ps_dbuffer.dbsize = arg;
295 		psp->ps_dbuffer.dbaddrs[1] = psp->ps_dbuffer.dbaddrs[0]+arg;
296 		psp->ps_dbuffer.state = ON_DB;
297 		psp->ps_dbuffer.rbuffer = 0;
298 		break;
299 
300 	case PSIOSINGLEBUFFER:
301 		psp->ps_dbuffer.state = OFF_DB;
302 		break;
303 
304 	case PSIOTIMEREFRESH:
305 		if (psp->ps_refresh.state != SINGLE_STEP_RF)
306 			return (EINVAL);
307 		if ((arg = fuword((caddr_t)waddr++)) == -1)
308 			return (EFAULT);
309 		psp->ps_refresh.state = TIME_RF;
310 		psp->ps_refresh.timecnt = arg;
311 		break;
312 
313 	case PSIOWAITREFRESH:
314 		if (psp->ps_refresh.mode != RUNNING_RF)	/* not running */
315 			return (0);			/* dont wait */
316 		/* fall into ... */
317 
318 	case PSIOSTOPREFRESH:
319 		if (cmd == PSIOSTOPREFRESH) {
320 			if (psp->ps_refresh.mode == STOPPED_RF &&
321 			    psp->ps_refresh.state != TIME_RF)
322 				return (0);
323 			psp->ps_refresh.stop = 1;
324 		}
325 		(void) spl5();
326 		psp->ps_refresh.waiting = 1;
327 		while (psp->ps_refresh.waiting)
328 			tsleep(&psp->ps_refresh.waiting, PSPRI,
329 				SLP_PS_REFRESH, 0);
330 		(void) spl0();
331 		if (cmd == PSIOSTOPREFRESH)
332 			psp->ps_refresh.mode = STOPPED_RF;
333 		if (psp->ps_refresh.state == TIME_RF)
334 			psp->ps_refresh.state = SINGLE_STEP_RF;
335 		break;
336 
337 	case PSIOWAITMAP:
338 		if (psp->ps_map.mode != RUNNING_MAP)	/* not running */
339 			return (0);			/* dont wait */
340 		/* fall into ... */
341 
342 	case PSIOSTOPMAP:
343 		if (cmd == PSIOSTOPMAP)
344 			psp->ps_map.stop = 1;
345 		(void) spl5();
346 		psp->ps_map.waiting = 1;
347 		while (psp->ps_map.waiting)
348 			tsleep(&psp->ps_map.waiting, PSPRI, SLP_PS_MAP, 0);
349 		(void) spl0();
350 		break;
351 
352 	default:
353 		return (ENOTTY);
354 		break;
355 	}
356 	return (0);
357 }
358 
359 #define SAVEPSADDR(psaddr, savepsaddr) { \
360 	register short i, xx1; \
361 	xx1 = splclock(); \
362 	i = psaddr->ps_addr; \
363 	while ((psaddr->ps_iostat & DIOREADY) == 0) \
364 		; \
365 	savepsaddr = psaddr->ps_data; \
366 	splx(xx1); \
367 }
368 #define RESTORPSADDR(psaddr, savepsaddr) { \
369 	register short xx2; \
370 	xx2 = splclock(); \
371 	while ((psaddr->ps_iostat & DIOREADY) == 0) \
372 		;\
373 	psaddr->ps_addr = savepsaddr; \
374 	splx(xx2); \
375 }
376 
377 psclockintr(dev)
378 	dev_t dev;
379 {
380 	register struct psdevice *psaddr =
381 	    (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
382 	register struct ps *psp = &ps[PSUNIT(dev)];
383 	int savepsaddr;
384 
385 	if (!psp->ps_open)
386 		return;
387 	psp->ps_clockcnt++;
388 	SAVEPSADDR(psaddr, savepsaddr);
389 #ifndef EXTERNAL_SYNC
390 	if (psp->ps_refresh.state == AUTO_RF) {
391 		if (psp->ps_refresh.mode == SYNCING_RF &&
392 		    psp->ps_refresh.state != TIME_RF) {
393 			(void) psrfnext(psp, psaddr);
394 		} else {
395 			psp->ps_clockticks++;
396 			psp->ps_clockmiss++;
397 		}
398 	}
399 #endif
400 	PSWAIT(psaddr); psaddr->ps_addr = RTCREQ;
401 	PSWAIT(psaddr); psaddr->ps_data = 01;	/* clear the request bits */
402 	RESTORPSADDR(psaddr, savepsaddr);
403 }
404 
405 /*ARGSUSED*/
406 pssystemintr(dev)
407 	dev_t dev;
408 {
409 	register struct psdevice *psaddr =
410 	    (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
411 	register struct ps *psp = &ps[PSUNIT(dev)];
412 	short request, tmp;
413 	register int savepsaddr, x;
414 
415 	if (!psp->ps_open)
416 		return;
417 	psp->ps_icnt++;
418 	SAVEPSADDR(psaddr, savepsaddr);
419 	PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
420 	PSWAIT(psaddr); request = psaddr->ps_data;
421 	request = request&0377;
422 	psp->ps_lastrequest2 = psp->ps_lastrequest;
423 	psp->ps_lastrequest = request;
424 	if (request &~ (HALT_REQ|RFSTOP_REQ|HIT_REQ)) {
425 		psp->ps_lastfunnyrequest = request;
426 		psp->ps_funnycnt++;
427 	}
428 	PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
429 	tmp = request&(~(HALT_REQ|MOSTOP_REQ));	/* acknowledge */
430 	PSWAIT(psaddr); psaddr->ps_data = tmp;
431 
432 	if (request & (MOSTOP_REQ|HALT_REQ)) {	/* Map stopped */
433 		psp->ps_map.icnt++;
434 		psmapstop(psaddr, psp, request);/* kill it dead */
435 		if (psp->ps_map.waiting) {
436 			psp->ps_map.waiting = 0;
437 			wakeup(&psp->ps_map.waiting);
438 			if (psp->ps_map.stop) {
439 				psp->ps_map.stop = 0;
440 				goto tryrf;
441 			}
442 		}
443 		if (psp->ps_map.state == AUTO_MAP && !psmapnext(psp, psaddr)) {
444 			psp->ps_map.mcntr = 0;
445 			/* prepare for next round */
446 			pssetmapbounds(psp, psaddr);
447 			if (psp->ps_refresh.state == AUTO_RF) {
448 				if (psp->ps_refresh.mode == WAITING_MAP){
449 					if (psp->ps_dbuffer.state == ON_DB)
450 						/* fill other db */
451 						psdbswitch(psp, psaddr);
452 					else
453 						psp->ps_map.mode = WAITING_RF;
454 #ifdef EXTERNAL_SYNC
455 					x = splclock();
456 #endif
457 					(void) psrfnext(psp, psaddr);
458 #ifdef EXTERNAL_SYNC
459 					splx(x);
460 #endif
461 				} else
462 					psp->ps_map.mode = WAITING_RF;
463 			} else {	/* no auto refresh */
464 				if (psp->ps_dbuffer.state == ON_DB)
465 					/* fill other db */
466 					psdbswitch(psp, psaddr);
467 				else
468 					(void) psmapnext(psp, psaddr);
469 			}
470 		}
471 	}
472 tryrf:
473 	if (request & RFSTOP_REQ) {		/* Refresh stopped */
474 		psp->ps_refresh.icnt++;
475 		if (psp->ps_refresh.state == TIME_RF)
476 			if (--psp->ps_refresh.timecnt > 0)
477 				goto tryhit;
478 		psrfstop(psaddr, psp);
479 		if (psp->ps_refresh.waiting) {
480 			psp->ps_refresh.waiting = 0;
481 			wakeup(&psp->ps_refresh.waiting);
482 			if (psp->ps_refresh.stop) {
483 				psp->ps_refresh.stop = 0;
484 				goto tryhit;
485 			}
486 		}
487 		if (psp->ps_refresh.state == AUTO_RF)
488 			if (!psrfnext(psp, psaddr)) {	/* at end of refresh cycle */
489 				if (psp->ps_map.state == AUTO_MAP &&
490 				    psp->ps_map.mode == WAITING_RF) {
491 					if (psp->ps_dbuffer.state == ON_DB)
492 						psdbswitch(psp, psaddr);
493 					else
494 						(void) psmapnext(psp, psaddr);
495 				}
496 				psp->ps_refresh.srcntr = 0;
497 #ifdef EXTERNAL_SYNC
498 				x = splclock();
499 #endif
500 				psp->ps_refresh.mode = SYNCING_RF;
501 				if (psp->ps_clockticks)
502 					(void) psrfnext(psp, psaddr);
503 				psp->ps_clockticks = 0;
504 #ifdef EXTERNAL_SYNC
505 				splx(x);
506 #endif
507 			}
508 	}
509 tryhit:
510 	if (request & HIT_REQ)			/* Hit request */
511 		psp->ps_hitcnt++;
512 	if (request == 0)
513 		psp->ps_strayintr++;
514 	RESTORPSADDR(psaddr, savepsaddr);
515 }
516 
517 psrfnext(psp, psaddr)
518 	register struct ps *psp;
519 	register struct psdevice *psaddr;
520 {
521 	u_short start, last;
522 
523 	if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) {
524 		psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++],
525 		    0, psp, psaddr);
526 		return (1);
527 	}
528 	if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs &&
529 	    psp->ps_dbuffer.state == ON_DB) {
530 		start = psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer];
531 		last = start+psp->ps_dbuffer.dbsize;
532 		psrfstart(start, last, psp, psaddr);
533 		psp->ps_refresh.srcntr++;	/* flag for after dbuffer */
534 		return (1);
535 	}
536 	return (0);
537 }
538 
539 psrfstart(dfaddr, last, psp, psaddr)
540 	u_short dfaddr, last;
541 	register struct ps *psp;
542 	register struct psdevice *psaddr;
543 {
544 	short dummy;
545 
546 	PSWAIT(psaddr); psaddr->ps_addr = RFASA;
547 	PSWAIT(psaddr); psaddr->ps_data = dfaddr;
548 	PSWAIT(psaddr);
549 	if (last != 0)
550 		psaddr->ps_data = last;
551 	else
552 		dummy = psaddr->ps_data;/* just access to get to status reg */
553 	PSWAIT(psaddr); psaddr->ps_data = RFSTART;	/* may want | here */
554 	psp->ps_refresh.mode = RUNNING_RF;
555 }
556 
557 /*ARGSUSED*/
558 psrfstop(psaddr, psp)
559 	register struct psdevice *psaddr;
560 	register struct ps *psp;
561 {
562 
563 	PSWAIT(psaddr); psaddr->ps_addr = RFSR;
564 	PSWAIT(psaddr); psaddr->ps_data = 0;
565 }
566 
567 psdbswitch(psp, psaddr)
568 	register struct ps *psp;
569 	register struct psdevice *psaddr;
570 {
571 
572 	psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer;
573 	pssetmapbounds(psp, psaddr);
574 	(void) psmapnext(psp, psaddr);
575 }
576 
577 psmapnext(psp, psaddr)
578 	register struct ps *psp;
579 	register struct psdevice *psaddr;
580 {
581 
582 	if (psp->ps_map.mcntr < psp->ps_map.nmaddrs) {
583 		psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++],
584 		    psp, psaddr);
585 		return (1);
586 	}
587 	return (0);
588 }
589 
590 pssetmapbounds(psp, psaddr)
591 	register struct ps *psp;
592 	register struct psdevice *psaddr;
593 {
594 	u_short start, last;
595 
596 	PSWAIT(psaddr); psaddr->ps_addr = MAOL;
597 	PSWAIT(psaddr);
598 	if (psp->ps_dbuffer.state == ON_DB) {
599 		start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer];
600 		last = start+psp->ps_dbuffer.dbsize-2;   /* 2 for halt cmd */
601 		psaddr->ps_data = last;
602 		PSWAIT(psaddr); psaddr->ps_data = start;
603 	} else {
604 		start = psaddr->ps_data;	/* dummy: don't update limit */
605 		PSWAIT(psaddr); psaddr->ps_data = psp->ps_map.outputstart;
606 	}
607 }
608 
609 psmapstart(dfaddr, psp, psaddr)
610 	u_short dfaddr;
611 	register struct ps *psp;
612 	register struct psdevice *psaddr;
613 {
614 
615 	PSWAIT(psaddr); psaddr->ps_addr = MAIA;
616 	PSWAIT(psaddr); psaddr->ps_data = dfaddr;
617 	PSWAIT(psaddr); psaddr->ps_data = MAO|MAI;	/* may want more here */
618 	psp->ps_map.mode = RUNNING_MAP;
619 }
620 
621 int pskillcnt = 1;
622 
623 psmapstop(psaddr, psp, request)
624 	register struct psdevice *psaddr;
625 	register struct ps *psp;
626 	short request;
627 {
628 	register int i;
629 
630 	request &= HALT_REQ|MOSTOP_REQ; 	/* overkill?? */
631 	for (i = 0; i < pskillcnt; i++) {
632 		PSWAIT(psaddr); psaddr->ps_addr = MASR;
633 		PSWAIT(psaddr); psaddr->ps_data = IOUT;	/* zero MAI & MAO */
634 		PSWAIT(psaddr); psaddr->ps_addr = MAIA;
635 		PSWAIT(psaddr); psaddr->ps_data = 0;	/* 0 input addr reg */
636 		PSWAIT(psaddr); psaddr->ps_addr = MAOA;
637 		PSWAIT(psaddr); psaddr->ps_data = 0;	/* 0 output addr reg */
638 		PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
639 		PSWAIT(psaddr); psaddr->ps_data = request;
640 	}
641 	psp->ps_map.mode = STOPPED_MAP;
642 }
643 
644 /*ARGSUSED*/
645 psdeviceintr(dev)
646 	dev_t dev;
647 {
648 
649 	printf("ps device intr\n");
650 }
651 
652 /*ARGSUSED*/
653 psdmaintr(dev)
654 	dev_t dev;
655 {
656 
657 	printf("ps dma intr\n");
658 }
659 
660 /*ARGSUSED*/
661 psreset(uban)
662 	int uban;
663 {
664 
665 }
666 
667 /*ARGSUSED*/
668 psextsync(PC, PS)
669 {
670 	register int n;
671 	register struct psdevice *psaddr;
672 	register struct ps *psp;
673 	register int savepsaddr;
674 
675 #ifdef EXTERNAL_SYNC
676 	for (psp = ps, n = 0; n < NPS; psp++, n++) {
677 		if (!psp->ps_open)
678 			continue;
679 		if (psp->ps_refresh.mode == SYNCING_RF &&
680 		    psp->ps_refresh.state != TIME_RF) {
681 			psaddr = (struct psdevice *)psdinfo[n]->ui_addr;
682 			SAVEPSADDR(psaddr, savepsaddr);
683 			(void) psrfnext(psp, psaddr);
684 			RESTORPSADDR(psaddr, savepsaddr);
685 		} else {
686 			psp->ps_clockticks++;
687 			psp->ps_clockmiss++;
688 		}
689 	}
690 #endif
691 }
692 #endif
693