* 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.
* @(#)va.c 7.1 (Berkeley) %G%
#include "../machine/pte.h"
#define dprintf if(vadebug)printf
u_short vaba
; /* buffer address */
short vawc
; /* word count (2's complement) */
short Vacsw
; /* control status as word */
struct { /* control status as bytes */
short vadata
; /* programmed i/o data buffer */
#define vacsh vacs.vacsr.Vacsh
#define vacsl vacs.vacsr.Vacsl
#define VA_ERROR 0100000 /* some error has occurred */
#define VA_NPRTIMO 0001000 /* DMA timeout error */
#define VA_NOTREADY 0000400 /* something besides NPRTIMO */
#define VA_IENABLE 0000100 /* interrupt enable */
#define VA_DMAGO 0000010 /* DMA go bit */
#define VA_DMAGO 0000010 /* DMA go bit */
#define VA_SUPPLIESLOW 0000004
#define VA_BOTOFFORM 0000002
#define VA_BYTEREVERSE 0000001 /* reverse byte order in words */
/* vacsh command bytes */
#define VAPRINTPLOT 0000160
#define VAAUTOSTEP 0000244
#define VANOAUTOSTEP 0000045
#define VAFORMFEED 0000263
u_char sc_openf
; /* exclusive open flag */
u_char sc_iostate
; /* kind of I/O going on */
#define VAS_IDLE 0 /* no I/O, free */
#define VAS_PIO 1 /* programmed I/O */
#define VAS_DMA 2 /* DMA, block pio */
#define VAS_WANT 4 /* wakeup when iostate changes */
short sc_tocnt
; /* time out counter */
short sc_info
; /* csw passed from vaintr */
int sc_state
; /* print/plot state of device */
#define VAUNIT(dev) (minor(dev))
int vaprobe(), vaslave(), vaattach(), vadgo();
struct uba_device
*vadinfo
[NVA
];
struct uba_ctlr
*vaminfo
[NVA
];
u_short vastd
[] = { 0764000, 0 };
struct uba_driver vadriver
=
{ vaprobe
, vaslave
, vaattach
, vadgo
, vastd
, "vz", vadinfo
, "va", vaminfo
};
register int br
, cvec
; /* value-result */
register struct vadevice
*vaaddr
= (struct vadevice
*)reg
;
br
= 0; cvec
= br
; br
= cvec
;
vaaddr
->vacsl
= VA_IENABLE
;
vaaddr
->vacsl
= VA_IENABLE
|VA_DMAGO
;
return (sizeof (struct vadevice
));
return (ui
->ui_unit
<= 0);
ui
->ui_mi
->um_tab
.b_actf
= &vabhdr
[ui
->ui_unit
];
register struct va_softc
*sc
;
register struct vadevice
*vaaddr
;
register struct uba_device
*ui
;
if (unit
>= NVA
|| (sc
= &va_softc
[unit
])->sc_openf
||
(ui
= vadinfo
[unit
]) == 0 || ui
->ui_alive
== 0)
vaaddr
= (struct vadevice
*)ui
->ui_addr
;
sc
->sc_iostate
= VAS_IDLE
;
vaaddr
->vacsl
= VA_IENABLE
;
error
= vacmd(dev
, VPRINT
);
register struct uba_device
*ui
;
register struct uba_ctlr
*um
;
dprintf("vastrategy(%x)\n", bp
);
ui
= vadinfo
[VAUNIT(bp
->b_dev
)];
if (ui
== 0 || ui
->ui_alive
== 0) {
if (um
->um_tab
.b_actf
->b_actf
== NULL
)
um
->um_tab
.b_actf
->b_actf
= bp
;
printf("bp = 0x%x, um->um_tab.b_actf->b_actf = 0x%x\n",
bp
, um
->um_tab
.b_actf
->b_actf
);
um
->um_tab
.b_actf
->b_actl
->b_forw
= bp
;
um
->um_tab
.b_actf
->b_actl
= bp
;
dprintf("vastrategy: bp=%x actf=%x active=%d\n",
bp
, bp
->b_actf
, bp
->b_active
);
if (bp
->b_actf
&& bp
->b_active
== 0)
if (bp
->b_bcount
> vablock
)
return (physio(vastrategy
, &rvabuf
[VAUNIT(dev
)], dev
, B_WRITE
,
register struct uba_ctlr
*um
;
register struct va_softc
*sc
;
dprintf("vastart(%x), bp=%x\n", um
, um
->um_tab
.b_actf
->b_actf
);
if ((bp
= um
->um_tab
.b_actf
->b_actf
) == NULL
)
unit
= VAUNIT(bp
->b_dev
);
while (sc
->sc_iostate
&VAS_PIO
) {
sc
->sc_iostate
|= VAS_WANT
;
sleep((caddr_t
)&sc
->sc_iostate
, VAPRI
);
sc
->sc_iostate
|= VAS_DMA
;
vaaddr
= (struct vadevice
*)um
->um_addr
;
vaaddr
->vawc
= -(bp
->b_bcount
/ 2);
um
->um_cmd
= VA_DMAGO
| VA_IENABLE
;
(void) ubago(vadinfo
[unit
]);
register struct uba_ctlr
*um
;
register struct vadevice
*vaaddr
= (struct vadevice
*)um
->um_addr
;
va_softc
[VAUNIT(bp
->b_actf
->b_dev
)].sc_tocnt
= 0;
vaaddr
->vaba
= um
->um_ubinfo
;
vaaddr
->vacsl
= ((um
->um_ubinfo
>> 12) & 0x30) | um
->um_cmd
;
vaioctl(dev
, cmd
, data
, flag
)
register struct va_softc
*sc
= &va_softc
[VAUNIT(dev
)];
*(int *)data
= sc
->sc_state
;
return (vacmd(dev
, *(int *)data
));
register struct va_softc
*sc
= &va_softc
[VAUNIT(dev
)];
while (sc
->sc_iostate
&VAS_DMA
) {
sc
->sc_iostate
|= VAS_WANT
;
sleep((caddr_t
)&sc
->sc_iostate
, VAPRI
);
sc
->sc_iostate
|= VAS_PIO
;
/* Must turn on plot AND autostep modes. */
if (vadopio(dev
, VAPLOT
))
sc
->sc_state
= (sc
->sc_state
& ~(VPLOT
|VPRINT
|VPRINTPLOT
)) | vcmd
;
if (cmd
&& vadopio(dev
, cmd
))
sc
->sc_iostate
&= ~VAS_PIO
;
if (sc
->sc_iostate
&VAS_WANT
) {
sc
->sc_iostate
&= ~VAS_WANT
;
wakeup((caddr_t
)&sc
->sc_iostate
);
register struct vadevice
*vaaddr
=
(struct vadevice
*)vaminfo
[VAUNIT(dev
)]->um_addr
;
register struct va_softc
*sc
= &va_softc
[VAUNIT(dev
)];
while ((sc
->sc_info
&(VA_DONE
|VA_ERROR
)) == 0)
sleep((caddr_t
)&sc
->sc_info
, VAPRI
);
return (sc
->sc_info
&VA_ERROR
);
register struct va_softc
*sc
= &va_softc
[VAUNIT(dev
)];
timeout(vatimo
, (caddr_t
)dev
, hz
/2);
dprintf("vatimo: calling vaintr\n");
register struct uba_ctlr
*um
;
register int unit
= VAUNIT(dev
), e
;
register struct va_softc
*sc
= &va_softc
[unit
];
vaaddr
= (struct vadevice
*)um
->um_addr
;
dprintf("vaintr: um=0x%x, e=0x%x, b_active %d\n",
um
, e
, um
->um_tab
.b_actf
->b_active
);
if ((e
&(VA_DONE
|VA_ERROR
)) == 0)
if ((e
&VA_ERROR
) && (e
&VA_NPRTIMO
))
printf("va%d: npr timeout\n", unit
);
if (sc
->sc_iostate
&VAS_PIO
) {
wakeup((caddr_t
)&sc
->sc_info
);
if (um
->um_tab
.b_actf
->b_active
) {
bp
= um
->um_tab
.b_actf
->b_actf
;
if (sc
->sc_state
&VPRINTPLOT
) {
sc
->sc_state
= (sc
->sc_state
& ~VPRINTPLOT
) | VPLOT
;
vaaddr
->vacsh
= VAAUTOSTEP
;
um
->um_tab
.b_actf
->b_active
= 0;
um
->um_tab
.b_actf
->b_actf
= bp
->b_forw
;
if (um
->um_tab
.b_actf
->b_actf
== 0) {
sc
->sc_iostate
&= ~VAS_DMA
;
if (sc
->sc_iostate
&VAS_WANT
) {
sc
->sc_iostate
&= ~VAS_WANT
;
wakeup((caddr_t
)&sc
->sc_iostate
);
if (um
->um_tab
.b_actf
->b_active
== 0)
register struct va_softc
*sc
= &va_softc
[VAUNIT(dev
)];
register struct vadevice
*vaaddr
=
(struct vadevice
*)vadinfo
[VAUNIT(dev
)]->ui_addr
;
if (sc
->sc_iostate
!= VAS_IDLE
)
wakeup((caddr_t
)&sc
->sc_iostate
);
sc
->sc_iostate
= VAS_IDLE
;
register struct uba_ctlr
*um
;
register struct vadevice
*vaaddr
;
register struct va_softc
*sc
;
for (va11
= 0; va11
< NVA
; va11
++, sc
++) {
if ((um
= vaminfo
[va11
]) == 0 || um
->um_ubanum
!= uban
||
sc
= &va_softc
[um
->um_ctlr
];
vaaddr
= (struct vadevice
*)um
->um_addr
;
vaaddr
->vacsl
= VA_IENABLE
;
if (sc
->sc_state
& VPLOT
) {
vaaddr
->vacsh
= VAAUTOSTEP
;
} else if (sc
->sc_state
& VPRINTPLOT
)
vaaddr
->vacsh
= VPRINTPLOT
;
vaaddr
->vacsh
= VAPRINTPLOT
;
sc
->sc_iostate
= VAS_IDLE
;
um
->um_tab
.b_actf
->b_active
= 0;
um
->um_tab
.b_actf
->b_actf
= um
->um_tab
.b_actf
->b_actl
= 0;
printf("<%d>", (um
->um_ubinfo
>> 28) & 0xf);