* Copyright (c) 1982 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)ct.c 6.4 (Berkeley) %G%
* GP DR11C driver used for C/A/T or Autologic APS micro-5
#include "../machine/pte.h"
int ctprobe(), ctattach(), ctintr();
struct uba_device
*ctdinfo
[NCT
];
u_short ctstd
[] = { 0167770, 0 };
struct uba_driver ctdriver
=
{ ctprobe
, 0, ctattach
, 0, ctstd
, "ct", ctdinfo
};
#define CTUNIT(dev) (minor(dev))
int ct_init
= 0; /* set to CSR1 for testing loopback on controller */
register int br
, cvec
; /* value-result */
register struct ctdevice
*ctaddr
= (struct ctdevice
*)reg
;
br
= 0; cvec
= br
; br
= cvec
;
* There is no way to make a DR11c interrupt without some
* external support. We can't always trust that the typesetter
* will be online and ready so we've made other provisions.
* This probe assumes setting the B Int Enb will generate
* an interrupt. To do this, we set CSR0 and loop this back
* to REQUEST_B in the second plug on the controller.
* Then, we reset the vector to be that for the "real" device.
ctaddr
->ctcsr
= INT_ENB_B
| CSR0
; /* Assume hardware loopback! */
ctaddr
->ctcsr
= ct_init
; /* should be CSR1 for loopback testing */
printf("ct: resetting vector %o to %o\n", cvec
, cvec
&0773);
return (sizeof (struct ctdevice
));
register struct uba_device
*ui
;
register struct ct_softc
*sc
;
register struct uba_device
*ui
;
register struct ctdevice
*ctaddr
;
if (CTUNIT(dev
) >= NCT
|| (ui
= ctdinfo
[CTUNIT(dev
)]) == 0 ||
if ((sc
= &ct_softc
[CTUNIT(dev
)])->sc_state
&CT_OPEN
)
ctaddr
= (struct ctdevice
*)ui
->ui_addr
;
ctaddr
->ctcsr
|= INT_ENB_A
;
ct_softc
[CTUNIT(dev
)].sc_state
= 0;
register struct ct_softc
*sc
= &ct_softc
[CTUNIT(dev
)];
while ((c
= uwritec(uio
)) >= 0) {
while (sc
->sc_oq
.c_cc
> CATHIWAT
)
sleep((caddr_t
)&sc
->sc_oq
, PCAT
);
while (putc(c
, &sc
->sc_oq
) < 0)
sleep((caddr_t
)&lbolt
, PCAT
);
if ( ! (sc
->sc_state
& CT_RUNNING
) )
* The C/A/T is usually wired to accept data on the .5us DATA_AVAIL strobe.
* If you use this with a C/A/T you can remove the lines with "APSu5" below.
* This is way out of spec for the Autologic APS micro-5 which requires
* at least a 40 microsec strobe. We therefore use CSR1 output as the
* "strobe". It is set after data is loaded and reset only in the
* interrupt routine. Therefore, the "strobe" is high for adequate time.
* The constant "ctdelay" determines the "low" time for the strobe
* and may have to be larger on a 780. "2" gives about 10us on a 750.
int ctdelay
= 2; /* here so it's visible & changeable */
register struct ct_softc
*sc
= &ct_softc
[CTUNIT(dev
)];
register struct ctdevice
*ctaddr
=
(struct ctdevice
*)ctdinfo
[CTUNIT(dev
)]->ui_addr
;
if ((ctaddr
->ctcsr
&(INT_ENB_B
|REQUEST_B
)) == (INT_ENB_B
|REQUEST_B
)) {
ctaddr
->ctcsr
&= ~(CSR0
| INT_ENB_B
); /* set in ctprobe */
if ((ctaddr
->ctcsr
&(INT_ENB_A
|REQUEST_A
)) == (INT_ENB_A
|REQUEST_A
)) {
if ((c
= getc(&sc
->sc_oq
)) >= 0) {
ctaddr
->ctcsr
&= ~CSR1
; /* APSu5 - drop strobe */
DELAY(ctdelay
); /* APSu5 - pause a bit */
ctaddr
->ctcsr
|= CSR1
; /* APSu5 - raise strobe */
sc
->sc_state
|= CT_RUNNING
;
if (sc
->sc_oq
.c_cc
==0 || sc
->sc_oq
.c_cc
==CATLOWAT
)
} else if (sc
->sc_state
== 0) {
sc
->sc_state
&= ~CT_RUNNING
;