Fix map register/DMA wait queues.
Still to do: BDP handling. Currently missing. Ubareset's won't work at all.
This commit is contained in:
parent
3bb07459cd
commit
a2692d780b
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dhu.c,v 1.15 1999/05/28 20:17:29 ragge Exp $ */
|
||||
/* $NetBSD: dhu.c,v 1.16 1999/06/06 19:14:48 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996 Ken C. Wellsch. All rights reserved.
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -71,10 +71,11 @@ struct dhu_softc {
|
|||
int sc_type; /* controller type, DHU or DHV */
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
bus_dma_tag_t sc_dmat;
|
||||
struct {
|
||||
struct tty *dhu_tty; /* what we work on */
|
||||
bus_dmamap_t dhu_dmah;
|
||||
int dhu_state; /* to manage TX output status */
|
||||
int dhu_txaddr; /* UBA map address to TX buf */
|
||||
short dhu_cc; /* character count on TX */
|
||||
short dhu_modem; /* modem bits state */
|
||||
} sc_dhu[NDHULINE];
|
||||
|
@ -207,10 +208,11 @@ dhu_attach(parent, self, aux)
|
|||
register struct dhu_softc *sc = (void *)self;
|
||||
register struct uba_attach_args *ua = aux;
|
||||
register unsigned c;
|
||||
register int n;
|
||||
register int n, i;
|
||||
|
||||
sc->sc_iot = ua->ua_iot;
|
||||
sc->sc_ioh = ua->ua_ioh;
|
||||
sc->sc_dmat = ua->ua_dmat;
|
||||
/* Process the 8 bytes of diagnostic info put into */
|
||||
/* the FIFO following the master reset operation. */
|
||||
|
||||
|
@ -233,6 +235,18 @@ dhu_attach(parent, self, aux)
|
|||
sc->sc_type = (c & DHU_STAT_DHU)? IS_DHU: IS_DHV;
|
||||
printf("\n%s: DH%s-11\n", self->dv_xname, (c & DHU_STAT_DHU)?"U":"V");
|
||||
|
||||
for (i = 0; i < sc->sc_type; i++) {
|
||||
struct tty *tp;
|
||||
tp = sc->sc_dhu[i].dhu_tty = ttymalloc();
|
||||
sc->sc_dhu[i].dhu_state = STATE_IDLE;
|
||||
bus_dmamap_create(sc->sc_dmat, tp->t_outq.c_cn, 1,
|
||||
tp->t_outq.c_cn, 0, BUS_DMA_ALLOCNOW|BUS_DMA_NOWAIT,
|
||||
&sc->sc_dhu[i].dhu_dmah);
|
||||
bus_dmamap_load(sc->sc_dmat, sc->sc_dhu[i].dhu_dmah,
|
||||
tp->t_outq.c_cs, tp->t_outq.c_cn, 0, BUS_DMA_NOWAIT);
|
||||
|
||||
}
|
||||
|
||||
/* Now stuff TX interrupt handler in place */
|
||||
scb_vecalloc(ua->ua_cvec + 4, dhuxint, self->dv_unit, SCB_ISTACK);
|
||||
}
|
||||
|
@ -365,24 +379,12 @@ dhuopen(dev, flag, mode, p)
|
|||
if (line >= sc->sc_type)
|
||||
return ENXIO;
|
||||
|
||||
tp = sc->sc_dhu[line].dhu_tty;
|
||||
if (tp == NULL) {
|
||||
|
||||
tp = sc->sc_dhu[line].dhu_tty = ttymalloc();
|
||||
if (tp == NULL)
|
||||
return ENXIO;
|
||||
|
||||
sc->sc_dhu[line].dhu_state = STATE_IDLE;
|
||||
|
||||
sc->sc_dhu[line].dhu_txaddr =
|
||||
uballoc((struct uba_softc *)sc->sc_dev.dv_parent,
|
||||
tp->t_outq.c_cs, tp->t_outq.c_cn, 0);
|
||||
|
||||
s = spltty();
|
||||
DHU_WRITE_BYTE(DHU_UBA_CSR, DHU_CSR_RXIE | line);
|
||||
sc->sc_dhu[line].dhu_modem = DHU_READ_WORD(DHU_UBA_STAT);
|
||||
(void) splx(s);
|
||||
}
|
||||
|
||||
tp = sc->sc_dhu[line].dhu_tty;
|
||||
|
||||
tp->t_oproc = dhustart;
|
||||
tp->t_param = dhuparam;
|
||||
|
@ -634,7 +636,7 @@ dhustart(tp)
|
|||
|
||||
sc->sc_dhu[line].dhu_state = STATE_DMA_RUNNING;
|
||||
|
||||
addr = UBAI_ADDR(sc->sc_dhu[line].dhu_txaddr) +
|
||||
addr = sc->sc_dhu[line].dhu_dmah->dm_segs[0].ds_addr +
|
||||
(tp->t_outq.c_cf - tp->t_outq.c_cs);
|
||||
|
||||
DHU_WRITE_WORD(DHU_UBA_TBUFCNT, cc);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dl.c,v 1.9 1999/05/27 16:00:45 ragge Exp $ */
|
||||
/* $NetBSD: dl.c,v 1.10 1999/06/06 19:14:49 ragge Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -97,10 +97,9 @@
|
|||
#include <machine/bus.h>
|
||||
#include <machine/scb.h>
|
||||
|
||||
#include <dev/dec/qbus/ubareg.h>
|
||||
#include <dev/dec/qbus/ubavar.h>
|
||||
#include <dev/qbus/ubavar.h>
|
||||
|
||||
#include <dev/dec/qbus/dlreg.h>
|
||||
#include <dev/qbus/dlreg.h>
|
||||
|
||||
#include "ioconf.h"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dz.c,v 1.17 1999/05/27 16:02:32 ragge Exp $ */
|
||||
/* $NetBSD: dz.c,v 1.18 1999/06/06 19:14:49 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996 Ken C. Wellsch. All rights reserved.
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -61,11 +61,8 @@
|
|||
#include <machine/trap.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <dev/dec/qbus/ubareg.h>
|
||||
#include <dev/dec/qbus/ubavar.h>
|
||||
|
||||
#include <dev/dec/qbus/dzreg.h>
|
||||
#include <dev/dec/qbus/dzvar.h>
|
||||
#include <dev/qbus/dzreg.h>
|
||||
#include <dev/qbus/dzvar.h>
|
||||
|
||||
#define DZ_READ_BYTE(adr) \
|
||||
bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->sc_dr.adr)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dz_uba.c,v 1.6 1999/05/27 16:02:50 ragge Exp $ */
|
||||
/* $NetBSD: dz_uba.c,v 1.7 1999/06/06 19:14:49 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1998 Ludd, University of Lule}, Sweden. All rights reserved.
|
||||
* Copyright (c) 1996 Ken C. Wellsch. All rights reserved.
|
||||
|
@ -49,11 +49,10 @@
|
|||
#include <machine/trap.h>
|
||||
#include <machine/scb.h>
|
||||
|
||||
#include <dev/dec/qbus/ubareg.h>
|
||||
#include <dev/dec/qbus/ubavar.h>
|
||||
#include <dev/qbus/ubavar.h>
|
||||
|
||||
#include <dev/dec/qbus/dzreg.h>
|
||||
#include <dev/dec/qbus/dzvar.h>
|
||||
#include <dev/qbus/dzreg.h>
|
||||
#include <dev/qbus/dzvar.h>
|
||||
|
||||
#include "ioconf.h"
|
||||
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
# $NetBSD: files.uba,v 1.4 1999/05/27 16:03:57 ragge Exp $
|
||||
# $NetBSD: files.uba,v 1.5 1999/06/06 19:14:49 ragge Exp $
|
||||
#
|
||||
# Config file and device description for machine-independent
|
||||
# code for devices Digital Equipment Corp. Unibus and Q22 bus.
|
||||
# Included by ports that need it.
|
||||
device uba { csr }
|
||||
|
||||
file dev/dec/uba/uba.c uba & new_uba
|
||||
file dev/qbus/uba.c uba & new_uba
|
||||
|
||||
# DZ-11 (-compatible) tty device driver.
|
||||
device dz { }: tty
|
||||
attach dz at uba with dz_uba
|
||||
file dev/dec/qbus/dz.c dz needs-flag
|
||||
file dev/dec/qbus/dz_uba.c dz_uba & new_uba
|
||||
file dev/qbus/dz.c dz needs-flag
|
||||
file dev/qbus/dz_uba.c dz_uba & new_uba
|
||||
|
||||
# DL-11 at UBA
|
||||
device dl: tty
|
||||
attach dl at uba
|
||||
file dev/dec/qbus/dl.c dl needs-flag
|
||||
file dev/qbus/dl.c dl needs-flag
|
||||
|
||||
# DHU-11 at UBA
|
||||
device dhu: tty
|
||||
attach dhu at uba
|
||||
file dev/qbus/dhu.c dhu needs-flag
|
||||
|
||||
device mtc: mscp
|
||||
attach mtc at uba
|
||||
device uda: mscp
|
||||
attach uda at uba
|
||||
file dev/qbus/uda.c uda | mtc
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uba.c,v 1.46 1999/05/27 16:04:13 ragge Exp $ */
|
||||
/* $NetBSD: uba.c,v 1.47 1999/06/06 19:14:49 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996 Jonathan Stone.
|
||||
* Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden.
|
||||
|
@ -58,261 +58,52 @@
|
|||
#include <machine/scb.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#ifdef __vax__
|
||||
#include <machine/pte.h>
|
||||
#endif
|
||||
#include <dev/qbus/ubavar.h>
|
||||
|
||||
#include <dev/dec/qbus/ubareg.h>
|
||||
#include <dev/dec/qbus/ubavar.h>
|
||||
#include "ioconf.h"
|
||||
|
||||
static int ubasearch __P((struct device *, struct cfdata *, void *));
|
||||
static int ubaprint __P((void *, const char *));
|
||||
static void ubainitmaps __P((struct uba_softc *));
|
||||
|
||||
extern struct cfdriver uba_cd;
|
||||
|
||||
#define spluba spl7
|
||||
|
||||
/*
|
||||
* Do transfer on device argument. The controller
|
||||
* and uba involved are implied by the device.
|
||||
* We queue for resource wait in the uba code if necessary.
|
||||
* We return 1 if the transfer was started, 0 if it was not.
|
||||
*
|
||||
* The onq argument must be zero iff the device is not on the
|
||||
* queue for this UBA. If onq is set, the device must be at the
|
||||
* head of the queue. In any case, if the transfer is started,
|
||||
* the device will be off the queue, and if not, it will be on.
|
||||
*
|
||||
* Drivers that allocate one BDP and hold it for some time should
|
||||
* set ud_keepbdp. In this case um_bdp tells which BDP is allocated
|
||||
* to the controller, unless it is zero, indicating that the controller
|
||||
* does not now have a BDP.
|
||||
* If we failed to allocate uba resources, put us on a queue to wait
|
||||
* until there is available resources. Resources to compete about
|
||||
* are map registers and BDPs. This is normally only a problem on
|
||||
* Unibus systems, Qbus systems have more map registers than usable.
|
||||
*/
|
||||
int
|
||||
ubaqueue(uu, bp)
|
||||
register struct uba_unit *uu;
|
||||
struct buf *bp;
|
||||
void
|
||||
uba_enqueue(uu)
|
||||
struct uba_unit *uu;
|
||||
{
|
||||
register struct uba_softc *uh;
|
||||
register int s;
|
||||
struct uba_softc *uh;
|
||||
int s;
|
||||
|
||||
uh = (void *)((struct device *)(uu->uu_softc))->dv_parent;
|
||||
s = spluba();
|
||||
/*
|
||||
* Honor exclusive BDP use requests.
|
||||
*/
|
||||
if ((uu->uu_xclu && uh->uh_users > 0) || uh->uh_xclu)
|
||||
goto rwait;
|
||||
if (uu->uu_keepbdp) {
|
||||
/*
|
||||
* First get just a BDP (though in fact it comes with
|
||||
* one map register too).
|
||||
*/
|
||||
if (uu->uu_bdp == 0) {
|
||||
uu->uu_bdp = uballoc(uh, (caddr_t)0, 0,
|
||||
UBA_NEEDBDP|UBA_CANTWAIT);
|
||||
if (uu->uu_bdp == 0)
|
||||
goto rwait;
|
||||
}
|
||||
/* now share it with this transfer */
|
||||
uu->uu_ubinfo = ubasetup(uh, bp,
|
||||
uu->uu_bdp|UBA_HAVEBDP|UBA_CANTWAIT);
|
||||
} else
|
||||
uu->uu_ubinfo = ubasetup(uh, bp, UBA_NEEDBDP|UBA_CANTWAIT);
|
||||
if (uu->uu_ubinfo == 0)
|
||||
goto rwait;
|
||||
uh->uh_users++;
|
||||
if (uu->uu_xclu)
|
||||
uh->uh_xclu = 1;
|
||||
|
||||
splx(s);
|
||||
return (1);
|
||||
|
||||
rwait:
|
||||
s = splimp();
|
||||
SIMPLEQ_INSERT_TAIL(&uh->uh_resq, uu, uu_resq);
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ubadone(uu)
|
||||
struct uba_unit *uu;
|
||||
{
|
||||
struct uba_softc *uh = (void *)((struct device *)
|
||||
(uu->uu_softc))->dv_parent;
|
||||
|
||||
if (uu->uu_xclu)
|
||||
uh->uh_xclu = 0;
|
||||
uh->uh_users--;
|
||||
if (uu->uu_keepbdp)
|
||||
uu->uu_ubinfo &= ~BDPMASK; /* keep BDP for misers */
|
||||
ubarelse(uh, &uu->uu_ubinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and setup UBA map registers, and bdp's
|
||||
* Flags says whether bdp is needed, whether the caller can't
|
||||
* wait (e.g. if the caller is at interrupt level).
|
||||
* Return value encodes map register plus page offset,
|
||||
* bdp number and number of map registers.
|
||||
*/
|
||||
int
|
||||
ubasetup(uh, bp, flags)
|
||||
struct uba_softc *uh;
|
||||
struct buf *bp;
|
||||
int flags;
|
||||
{
|
||||
int npf;
|
||||
int temp;
|
||||
int reg, bdp;
|
||||
int a, o, ubinfo;
|
||||
|
||||
if (uh->uh_nbdp == 0)
|
||||
flags &= ~UBA_NEEDBDP;
|
||||
|
||||
o = (int)bp->b_un.b_addr & VAX_PGOFSET;
|
||||
npf = vax_btoc(bp->b_bcount + o) + 1;
|
||||
if (npf > UBA_MAXNMR)
|
||||
panic("uba xfer too big");
|
||||
a = spluba();
|
||||
while ((reg = rmalloc(uh->uh_map, (long)npf)) == 0) {
|
||||
if (flags & UBA_CANTWAIT) {
|
||||
splx(a);
|
||||
return (0);
|
||||
}
|
||||
uh->uh_mrwant++;
|
||||
sleep((caddr_t)&uh->uh_mrwant, PSWP);
|
||||
}
|
||||
if ((flags & UBA_NEED16) && reg + npf > 128) {
|
||||
/*
|
||||
* Could hang around and try again (if we can ever succeed).
|
||||
* Won't help any current device...
|
||||
*/
|
||||
rmfree(uh->uh_map, (long)npf, (long)reg);
|
||||
splx(a);
|
||||
return (0);
|
||||
}
|
||||
bdp = 0;
|
||||
if (flags & UBA_NEEDBDP) {
|
||||
while ((bdp = ffs((long)uh->uh_bdpfree)) == 0) {
|
||||
if (flags & UBA_CANTWAIT) {
|
||||
rmfree(uh->uh_map, (long)npf, (long)reg);
|
||||
splx(a);
|
||||
return (0);
|
||||
}
|
||||
uh->uh_bdpwant++;
|
||||
sleep((caddr_t)&uh->uh_bdpwant, PSWP);
|
||||
}
|
||||
uh->uh_bdpfree &= ~(1 << (bdp-1));
|
||||
} else if (flags & UBA_HAVEBDP)
|
||||
bdp = (flags >> 28) & 0xf;
|
||||
splx(a);
|
||||
reg--;
|
||||
ubinfo = UBAI_INFO(o, reg, npf, bdp);
|
||||
temp = (bdp << 21) | UBAMR_MRV;
|
||||
if (bdp && (o & 01))
|
||||
temp |= UBAMR_BO;
|
||||
|
||||
disk_reallymapin(bp, uh->uh_mr, reg, temp | PG_V);
|
||||
|
||||
return (ubinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* Non buffer setup interface... set up a buffer and call ubasetup.
|
||||
*/
|
||||
int
|
||||
uballoc(uh, addr, bcnt, flags)
|
||||
struct uba_softc *uh;
|
||||
caddr_t addr;
|
||||
int bcnt, flags;
|
||||
{
|
||||
struct buf ubabuf;
|
||||
|
||||
ubabuf.b_un.b_addr = addr;
|
||||
ubabuf.b_flags = B_BUSY;
|
||||
ubabuf.b_bcount = bcnt;
|
||||
/* that's all the fields ubasetup() needs */
|
||||
return (ubasetup(uh, &ubabuf, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* Release resources on uba uban, and then unblock resource waiters.
|
||||
* The map register parameter is by value since we need to block
|
||||
* against uba resets on 11/780's.
|
||||
* When a routine that uses resources is finished, the next device
|
||||
* in queue for map registers etc is called. If it succeeds to get
|
||||
* resources, call next, and next, and next...
|
||||
* This routine must be called at splimp.
|
||||
*/
|
||||
void
|
||||
ubarelse(uh, amr)
|
||||
uba_done(uh)
|
||||
struct uba_softc *uh;
|
||||
int *amr;
|
||||
{
|
||||
struct uba_unit *uu;
|
||||
register int bdp, reg, npf, s;
|
||||
int mr;
|
||||
|
||||
/*
|
||||
* Carefully see if we should release the space, since
|
||||
* it may be released asynchronously at uba reset time.
|
||||
*/
|
||||
s = spluba();
|
||||
mr = *amr;
|
||||
if (mr == 0) {
|
||||
/*
|
||||
* A ubareset() occurred before we got around
|
||||
* to releasing the space... no need to bother.
|
||||
*/
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
*amr = 0;
|
||||
bdp = UBAI_BDP(mr);
|
||||
if (bdp) {
|
||||
if (uh->uh_ubapurge)
|
||||
(*uh->uh_ubapurge)(uh, bdp);
|
||||
|
||||
uh->uh_bdpfree |= 1 << (bdp-1); /* atomic */
|
||||
if (uh->uh_bdpwant) {
|
||||
uh->uh_bdpwant = 0;
|
||||
wakeup((caddr_t)&uh->uh_bdpwant);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Put back the registers in the resource map.
|
||||
* The map code must not be reentered,
|
||||
* nor can the registers be freed twice.
|
||||
* Unblock interrupts once this is done.
|
||||
*/
|
||||
npf = UBAI_NMR(mr);
|
||||
reg = UBAI_MR(mr) + 1;
|
||||
rmfree(uh->uh_map, (long)npf, (long)reg);
|
||||
splx(s);
|
||||
|
||||
/*
|
||||
* Wakeup sleepers for map registers,
|
||||
* and also, if there are processes blocked in dgo(),
|
||||
* give them a chance at the UNIBUS.
|
||||
*/
|
||||
if (uh->uh_mrwant) {
|
||||
uh->uh_mrwant = 0;
|
||||
wakeup((caddr_t)&uh->uh_mrwant);
|
||||
}
|
||||
while ((uu = uh->uh_resq.sqh_first)) {
|
||||
while ((uu = SIMPLEQ_FIRST(&uh->uh_resq))) {
|
||||
SIMPLEQ_REMOVE_HEAD(&uh->uh_resq, uu, uu_resq);
|
||||
if ((*uu->uu_ready)(uu) == 0)
|
||||
if ((*uu->uu_ready)(uu) == 0) {
|
||||
SIMPLEQ_INSERT_HEAD(&uh->uh_resq, uu, uu_resq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ubainitmaps(uhp)
|
||||
register struct uba_softc *uhp;
|
||||
{
|
||||
|
||||
if (uhp->uh_memsize > UBA_MAXMR)
|
||||
uhp->uh_memsize = UBA_MAXMR;
|
||||
rminit(uhp->uh_map, (long)uhp->uh_memsize, (long)1, "uba", UAMSIZ);
|
||||
uhp->uh_bdpfree = (1 << uhp->uh_nbdp) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -327,16 +118,8 @@ ubareset(uban)
|
|||
register struct uba_softc *uh = uba_cd.cd_devs[uban];
|
||||
int s, i;
|
||||
|
||||
s = spluba();
|
||||
uh->uh_users = 0;
|
||||
uh->uh_zvcnt = 0;
|
||||
uh->uh_xclu = 0;
|
||||
s = splimp();
|
||||
SIMPLEQ_INIT(&uh->uh_resq);
|
||||
uh->uh_bdpwant = 0;
|
||||
uh->uh_mrwant = 0;
|
||||
ubainitmaps(uh);
|
||||
wakeup((caddr_t)&uh->uh_bdpwant);
|
||||
wakeup((caddr_t)&uh->uh_mrwant);
|
||||
printf("%s: reset", uh->uh_dev.dv_xname);
|
||||
(*uh->uh_ubainit)(uh);
|
||||
|
||||
|
@ -347,9 +130,7 @@ ubareset(uban)
|
|||
}
|
||||
|
||||
/*
|
||||
* The common attach routines:
|
||||
* Allocates interrupt vectors.
|
||||
* Puts correct values in uba_softc.
|
||||
* The common attach routine:
|
||||
* Calls the scan routine to search for uba devices.
|
||||
*/
|
||||
void
|
||||
|
@ -371,14 +152,6 @@ uba_attach(sc, iopagephys)
|
|||
*/
|
||||
if (bus_space_map(sc->uh_iot, iopagephys, UBAIOSIZE, 0, &sc->uh_ioh))
|
||||
return;
|
||||
/*
|
||||
* Initialize the UNIBUS, by freeing the map
|
||||
* registers and the buffered data path registers
|
||||
*/
|
||||
sc->uh_map = (struct map *)malloc((u_long)
|
||||
(UAMSIZ * sizeof(struct map)), M_DEVBUF, M_NOWAIT);
|
||||
bzero((caddr_t)sc->uh_map, (unsigned)(UAMSIZ * sizeof (struct map)));
|
||||
ubainitmaps(sc);
|
||||
|
||||
if (sc->uh_beforescan)
|
||||
(*sc->uh_beforescan)(sc);
|
||||
|
@ -403,6 +176,7 @@ ubasearch(parent, cf, aux)
|
|||
|
||||
ua.ua_ioh = ubdevreg(cf->cf_loc[0]) + sc->uh_ioh;
|
||||
ua.ua_iot = sc->uh_iot;
|
||||
ua.ua_dmat = sc->uh_dmat;
|
||||
ua.ua_reset = NULL;
|
||||
|
||||
if (badaddr((caddr_t)ua.ua_ioh, 2) ||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ubavar.h,v 1.24 1999/05/27 16:04:48 ragge Exp $ */
|
||||
/* $NetBSD: ubavar.h,v 1.25 1999/06/06 19:14:49 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986 Regents of the University of California.
|
||||
|
@ -44,10 +44,6 @@
|
|||
* Each unibus device has a uba_device structure.
|
||||
*/
|
||||
|
||||
#include <sys/buf.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/trap.h> /* For struct ivec_dsp */
|
||||
/*
|
||||
* Per-uba structure.
|
||||
*
|
||||
|
@ -72,39 +68,21 @@
|
|||
struct uba_softc {
|
||||
struct device uh_dev; /* Device struct, autoconfig */
|
||||
SIMPLEQ_HEAD(, uba_unit) uh_resq; /* resource wait chain */
|
||||
int uh_type; /* type of adaptor */
|
||||
struct uba_regs *uh_uba; /* virt addr of uba adaptor regs */
|
||||
struct pte *uh_mr; /* start of page map */
|
||||
int uh_memsize; /* size of uba memory, pages */
|
||||
caddr_t uh_iopage; /* start of uba io page */
|
||||
void (**uh_reset) __P((int));/* UBA reset function array */
|
||||
int *uh_resarg; /* array of ubareset args */
|
||||
int uh_resno; /* Number of devices to reset */
|
||||
short uh_mrwant; /* someone is waiting for map reg */
|
||||
short uh_bdpwant; /* someone awaits bdp's */
|
||||
int uh_bdpfree; /* free bdp's */
|
||||
int uh_zvcnt; /* number of recent 0 vectors */
|
||||
long uh_zvtime; /* time over which zvcnt accumulated */
|
||||
int uh_zvtotal; /* total number of 0 vectors */
|
||||
int uh_lastiv; /* last free interrupt vector */
|
||||
short uh_users; /* transient bdp use count */
|
||||
short uh_xclu; /* an rk07 is using this uba! */
|
||||
int uh_lastmem; /* limit of any unibus memory */
|
||||
struct map *uh_map; /* register free map */
|
||||
int (*uh_errchk) __P((struct uba_softc *));
|
||||
void (*uh_beforescan) __P((struct uba_softc *));
|
||||
void (*uh_afterscan) __P((struct uba_softc *));
|
||||
void (*uh_ubainit) __P((struct uba_softc *));
|
||||
void (*uh_ubapurge) __P((struct uba_softc *, int));
|
||||
short uh_nr; /* Unibus sequential number */
|
||||
short uh_nbdp; /* # of BDP's */
|
||||
int uh_ibase; /* Base address for vectors */
|
||||
bus_space_tag_t uh_iot; /* Tag for this Unibus */
|
||||
bus_space_handle_t uh_ioh; /* Handle for I/O space */
|
||||
bus_dma_tag_t uh_dmat;
|
||||
};
|
||||
|
||||
#define UAMSIZ 100
|
||||
|
||||
/*
|
||||
* Per-controller structure.
|
||||
* The unit struct is common to both the adapter and the controller
|
||||
|
@ -114,9 +92,9 @@ struct uba_softc {
|
|||
struct uba_unit {
|
||||
SIMPLEQ_ENTRY(uba_unit) uu_resq;/* Queue while waiting for resources */
|
||||
void *uu_softc; /* Pointer to units softc */
|
||||
int uu_ubinfo; /* save unibus registers, etc */
|
||||
int uu_bdp; /* for controllers that hang on to bdp's */
|
||||
int (*uu_ready) __P((struct uba_unit *));
|
||||
void *uu_ref; /* Buffer this is related to */
|
||||
short uu_xclu; /* want exclusive use of bdp's */
|
||||
short uu_keepbdp; /* hang on to bdp's once allocated */
|
||||
};
|
||||
|
@ -128,6 +106,7 @@ struct uba_unit {
|
|||
struct uba_attach_args {
|
||||
bus_space_tag_t ua_iot; /* Tag for this bus I/O-space */
|
||||
bus_addr_t ua_ioh; /* I/O regs addr */
|
||||
bus_dma_tag_t ua_dmat;
|
||||
/* Pointer to int routine, filled in by probe*/
|
||||
void (*ua_ivec) __P((int));
|
||||
/* UBA reset routine, filled in by probe */
|
||||
|
@ -144,44 +123,21 @@ struct uba_attach_args {
|
|||
#define UBA_CANTWAIT 0x02 /* don't block me */
|
||||
#define UBA_NEED16 0x04 /* need 16 bit addresses only */
|
||||
#define UBA_HAVEBDP 0x08 /* use bdp specified in high bits */
|
||||
#define UBA_DONTQUE 0x10 /* Do not enqueue xfer */
|
||||
|
||||
/*
|
||||
* Macros to bust return word from map allocation routines.
|
||||
* SHOULD USE STRUCTURE TO STORE UBA RESOURCE ALLOCATION:
|
||||
* Some common defines for all subtypes of U/Q-buses/adapters.
|
||||
*/
|
||||
#ifdef notyet
|
||||
struct ubinfo {
|
||||
long ub_addr; /* unibus address: mr + boff */
|
||||
int ub_nmr; /* number of registers, 0 if empty */
|
||||
int ub_bdp; /* bdp number, 0 if none */
|
||||
};
|
||||
#define UBAI_MR(i) (((i) >> 9) & 0x7ff) /* starting map register */
|
||||
#define UBAI_BOFF(i) ((i)&0x1ff) /* page offset */
|
||||
#else
|
||||
#define UBAI_BDP(i) ((int)(((unsigned)(i)) >> 28))
|
||||
#define BDPMASK 0xf0000000
|
||||
#define UBAI_NMR(i) ((int)((i) >> 20) & 0xff) /* max 255 (=127.5K) */
|
||||
#define UBA_MAXNMR 255
|
||||
#define UBAI_MR(i) ((int)((i) >> 9) & 0x7ff) /* max 2047 */
|
||||
#define UBA_MAXMR 2047
|
||||
#define UBAI_BOFF(i) ((int)((i) & 0x1ff))
|
||||
#define UBAI_ADDR(i) ((int)((i) & 0xfffff)) /* uba addr (boff+mr) */
|
||||
#define UBAI_INFO(off, mr, nmr, bdp) \
|
||||
(((bdp) << 28) | ((nmr) << 20) | ((mr) << 9) | (off))
|
||||
#endif
|
||||
#define MAXUBAXFER (63*1024) /* Max transfer size in bytes */
|
||||
#define UBAIOSIZE (8*1024) /* 8K I/O space */
|
||||
#define ubdevreg(addr) ((addr) & 017777)
|
||||
|
||||
#ifndef _LOCORE
|
||||
#ifdef _KERNEL
|
||||
#define ubago(ui) ubaqueue(ui)
|
||||
#define b_forw b_hash.le_next /* Nice to have when handling uba queues */
|
||||
|
||||
void uba_attach __P((struct uba_softc *, unsigned long));
|
||||
int uballoc __P((struct uba_softc *, caddr_t, int, int));
|
||||
void ubarelse __P((struct uba_softc *, int *));
|
||||
int ubaqueue __P((struct uba_unit *, struct buf *));
|
||||
void ubadone __P((struct uba_unit *));
|
||||
void uba_enqueue __P((struct uba_unit *));
|
||||
void uba_done __P((struct uba_softc *));
|
||||
void ubareset __P((int));
|
||||
int ubasetup __P((struct uba_softc *, struct buf *, int));
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif !_LOCORE
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uda.c,v 1.29 1999/05/29 17:03:17 ragge Exp $ */
|
||||
/* $NetBSD: uda.c,v 1.30 1999/06/06 19:14:49 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
|
@ -45,18 +45,20 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/sid.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <vax/uba/ubareg.h>
|
||||
#include <vax/uba/ubavar.h>
|
||||
#include <vax/uba/udareg.h>
|
||||
#include <dev/qbus/ubavar.h>
|
||||
|
||||
#include <vax/mscp/mscp.h>
|
||||
#include <vax/mscp/mscpvar.h>
|
||||
#include <vax/mscp/mscpreg.h>
|
||||
#include <dev/mscp/mscp.h>
|
||||
#include <dev/mscp/mscpreg.h>
|
||||
#include <dev/mscp/mscpvar.h>
|
||||
|
||||
#include "ioconf.h"
|
||||
|
||||
/*
|
||||
* Variants of SIMPLEQ macros for use with buf structs.
|
||||
|
@ -81,11 +83,15 @@ struct uda_softc {
|
|||
SIMPLEQ_HEAD(, buf) sc_bufq; /* bufs awaiting for resources */
|
||||
struct mscp_pack *sc_uuda; /* Unibus address of uda struct */
|
||||
struct mscp_pack sc_uda; /* Struct for uda communication */
|
||||
struct udadevice *sc_udadev; /* pointer to ip/sa regs */
|
||||
bus_dma_tag_t sc_dmat;
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_iph;
|
||||
bus_space_handle_t sc_sah;
|
||||
bus_dmamap_t sc_cmap;/* Control structures */
|
||||
struct mscp *sc_mscp; /* Keep pointer to active mscp */
|
||||
short sc_ipl; /* interrupt priority, Q-bus */
|
||||
struct mscp_softc *sc_softc; /* MSCP info (per mscpvar.h) */
|
||||
int sc_wticks; /* watchdog timer ticks */
|
||||
int sc_inq;
|
||||
};
|
||||
|
||||
static int udamatch __P((struct device *, struct cfdata *, void *));
|
||||
|
@ -97,19 +103,15 @@ static void udaintr __P((int));
|
|||
static void mtcintr __P((int));
|
||||
static void intr __P((struct uda_softc *));
|
||||
int udaready __P((struct uba_unit *));
|
||||
void udactlrdone __P((struct device *, int));
|
||||
void udactlrdone __P((struct device *));
|
||||
int udaprint __P((void *, const char *));
|
||||
void udasaerror __P((struct device *, int));
|
||||
int udago __P((struct device *, struct buf *));
|
||||
|
||||
extern struct cfdriver mtc_cd;
|
||||
void udago __P((struct device *, struct mscp_xi *));
|
||||
|
||||
struct cfattach mtc_ca = {
|
||||
sizeof(struct uda_softc), udamatch, udaattach
|
||||
};
|
||||
|
||||
extern struct cfdriver uda_cd;
|
||||
|
||||
struct cfattach uda_ca = {
|
||||
sizeof(struct uda_softc), udamatch, udaattach
|
||||
};
|
||||
|
@ -151,17 +153,15 @@ udamatch(parent, cf, aux)
|
|||
struct mscp_softc mi; /* Nice hack */
|
||||
struct uba_softc *ubasc;
|
||||
int tries;
|
||||
#if QBA && notyet
|
||||
extern volatile int rbr;
|
||||
int s;
|
||||
#endif
|
||||
|
||||
/* Get an interrupt vector. */
|
||||
ubasc = (void *)parent;
|
||||
ivec_no = ubasc->uh_lastiv - 4;
|
||||
|
||||
mi.mi_sa = &((struct udadevice *)ua->ua_addr)->udasa;
|
||||
mi.mi_ip = &((struct udadevice *)ua->ua_addr)->udaip;
|
||||
mi.mi_iot = ua->ua_iot;
|
||||
mi.mi_iph = ua->ua_ioh;
|
||||
mi.mi_sah = ua->ua_ioh + 2;
|
||||
mi.mi_swh = ua->ua_ioh + 2;
|
||||
|
||||
/*
|
||||
* Initialise the controller (partially). The UDA50 programmer's
|
||||
|
@ -171,28 +171,23 @@ udamatch(parent, cf, aux)
|
|||
* initialise within ten seconds. Or so I hear; I have not seen
|
||||
* this manual myself.
|
||||
*/
|
||||
#if 0
|
||||
s = spl6();
|
||||
#endif
|
||||
tries = 0;
|
||||
again:
|
||||
|
||||
*mi.mi_ip = 0;
|
||||
bus_space_write_2(mi.mi_iot, mi.mi_iph, 0, 0); /* Start init */
|
||||
if (mscp_waitstep(&mi, MP_STEP1, MP_STEP1) == 0)
|
||||
return 0; /* Nothing here... */
|
||||
|
||||
*mi.mi_sa = MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | MP_IE |
|
||||
(ivec_no >> 2);
|
||||
bus_space_write_2(mi.mi_iot, mi.mi_sah, 0,
|
||||
MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | MP_IE | (ivec_no >> 2));
|
||||
|
||||
if (mscp_waitstep(&mi, MP_STEP2, MP_STEP2) == 0) {
|
||||
printf("udaprobe: init step2 no change. sa=%x\n", *mi.mi_sa);
|
||||
printf("udaprobe: init step2 no change. sa=%x\n",
|
||||
bus_space_read_2(mi.mi_iot, mi.mi_sah, 0));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* should have interrupted by now */
|
||||
#if 0
|
||||
rbr = qbgetpri();
|
||||
#endif
|
||||
if (strcmp(cf->cf_driver->cd_name, mtc_cd.cd_name)) {
|
||||
ua->ua_ivec = udaintr;
|
||||
ua->ua_reset = udareset;
|
||||
|
@ -205,9 +200,6 @@ again:
|
|||
bad:
|
||||
if (++tries < 2)
|
||||
goto again;
|
||||
#if 0
|
||||
splx(s);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -220,17 +212,18 @@ udaattach(parent, self, aux)
|
|||
struct uba_attach_args *ua = aux;
|
||||
struct uba_softc *uh = (void *)parent;
|
||||
struct mscp_attach_args ma;
|
||||
int ctlr, ubinfo;
|
||||
int ctlr, error, rseg;
|
||||
bus_dma_segment_t seg;
|
||||
|
||||
printf("\n");
|
||||
|
||||
uh->uh_lastiv -= 4; /* remove dynamic interrupt vector */
|
||||
#ifdef QBA
|
||||
sc->sc_ipl = ua->ua_br;
|
||||
#endif
|
||||
|
||||
sc->sc_iot = ua->ua_iot;
|
||||
sc->sc_iph = ua->ua_ioh;
|
||||
sc->sc_sah = ua->ua_ioh + 2;
|
||||
sc->sc_dmat = ua->ua_dmat;
|
||||
ctlr = sc->sc_dev.dv_unit;
|
||||
sc->sc_udadev = (struct udadevice *)ua->ua_addr;
|
||||
SIMPLEQ_INIT(&sc->sc_bufq);
|
||||
|
||||
/*
|
||||
|
@ -244,16 +237,31 @@ udaattach(parent, self, aux)
|
|||
* Map the communication area and command and
|
||||
* response packets into Unibus space.
|
||||
*/
|
||||
ubinfo = uballoc((struct uba_softc *)sc->sc_dev.dv_parent,
|
||||
(caddr_t) &sc->sc_uda, sizeof (struct mscp_pack), UBA_CANTWAIT);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (ubinfo == 0) {
|
||||
printf("%s: uballoc map failed\n", sc->sc_dev.dv_xname);
|
||||
if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct mscp_pack),
|
||||
NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
|
||||
printf("Alloc ctrl area %d\n", error);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
sc->sc_uuda = (struct mscp_pack *) UBAI_ADDR(ubinfo);
|
||||
if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
|
||||
sizeof(struct mscp_pack), (caddr_t *) &sc->sc_uda,
|
||||
BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
|
||||
printf("Map ctrl area %d\n", error);
|
||||
err: bus_dmamem_free(sc->sc_dmat, &seg, rseg);
|
||||
return;
|
||||
}
|
||||
if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct mscp_pack),
|
||||
1, sizeof(struct mscp_pack), 0, BUS_DMA_NOWAIT, &sc->sc_cmap))) {
|
||||
printf("Create DMA map %d\n", error);
|
||||
err2: bus_dmamem_unmap(sc->sc_dmat, (caddr_t)&sc->sc_uda,
|
||||
sizeof(struct mscp_pack));
|
||||
goto err;
|
||||
}
|
||||
if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap,
|
||||
&sc->sc_uda, sizeof(struct mscp_pack), 0, BUS_DMA_NOWAIT))) {
|
||||
printf("Load ctrl map %d\n", error);
|
||||
bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
|
||||
goto err2;
|
||||
}
|
||||
|
||||
bzero(&sc->sc_uda, sizeof (struct mscp_pack));
|
||||
|
||||
|
@ -268,11 +276,14 @@ udaattach(parent, self, aux)
|
|||
|
||||
ma.ma_mc = &uda_mscp_ctlr;
|
||||
ma.ma_type |= MSCPBUS_UDA;
|
||||
ma.ma_uuda = sc->sc_uuda;
|
||||
ma.ma_uda = &sc->sc_uda;
|
||||
ma.ma_softc = &sc->sc_softc;
|
||||
ma.ma_ip = &sc->sc_udadev->udaip;
|
||||
ma.ma_sa = ma.ma_sw = &sc->sc_udadev->udasa;
|
||||
ma.ma_iot = sc->sc_iot;
|
||||
ma.ma_iph = sc->sc_iph;
|
||||
ma.ma_sah = sc->sc_sah;
|
||||
ma.ma_swh = sc->sc_sah;
|
||||
ma.ma_dmat = sc->sc_dmat;
|
||||
ma.ma_dmam = sc->sc_cmap;
|
||||
ma.ma_ivec = ivec_no;
|
||||
ma.ma_ctlrnr = (ua->ua_iaddr == 0172150 ? 0 : 1); /* XXX */
|
||||
ma.ma_adapnr = uh->uh_nr;
|
||||
|
@ -282,53 +293,63 @@ udaattach(parent, self, aux)
|
|||
/*
|
||||
* Start a transfer if there are free resources available, otherwise
|
||||
* let it go in udaready, forget it for now.
|
||||
* Called from mscp routines.
|
||||
*/
|
||||
int
|
||||
udago(usc, bp)
|
||||
void
|
||||
udago(usc, mxi)
|
||||
struct device *usc;
|
||||
struct buf *bp;
|
||||
struct mscp_xi *mxi;
|
||||
{
|
||||
struct uda_softc *sc = (void *)usc;
|
||||
struct uba_unit *uu = &sc->sc_unit;
|
||||
struct uba_unit *uu;
|
||||
struct buf *bp = mxi->mxi_bp;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* If we already are queued for resources, don't call ubaqueue
|
||||
* again. (Then we would trash the wait queue). Just queue the
|
||||
* buf and let the rest be done in udaready.
|
||||
* If we already have transfers queued, don't try to load
|
||||
* the map again.
|
||||
*/
|
||||
if (sc->sc_bufq.sqh_first)
|
||||
BUFQ_INSERT_TAIL(&sc->sc_bufq, bp)
|
||||
else {
|
||||
if (ubaqueue(uu, bp))
|
||||
mscp_dgo(sc->sc_softc, (UBAI_ADDR(uu->uu_ubinfo) |
|
||||
(UBAI_BDP(uu->uu_ubinfo) << 24)),uu->uu_ubinfo,bp);
|
||||
else
|
||||
BUFQ_INSERT_TAIL(&sc->sc_bufq, bp)
|
||||
if (sc->sc_inq == 0) {
|
||||
err = bus_dmamap_load(sc->sc_dmat, mxi->mxi_dmam,
|
||||
bp->b_un.b_addr,
|
||||
bp->b_bcount, bp->b_proc, BUS_DMA_NOWAIT);
|
||||
if (err == 0) {
|
||||
mscp_dgo(sc->sc_softc, mxi);
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
uu = malloc(sizeof(struct uba_unit), M_DEVBUF, M_NOWAIT);
|
||||
if (uu == 0)
|
||||
panic("udago: no mem");
|
||||
uu->uu_ready = udaready;
|
||||
uu->uu_softc = sc;
|
||||
uu->uu_ref = mxi;
|
||||
uba_enqueue(uu);
|
||||
sc->sc_inq++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called if we have been blocked for resources, and resources
|
||||
* have been freed again. Return 1 if we could start all
|
||||
* transfers again, 0 if we still are waiting.
|
||||
* Called from uba resource free routines.
|
||||
*/
|
||||
int
|
||||
udaready(uu)
|
||||
struct uba_unit *uu;
|
||||
{
|
||||
struct uda_softc *sc = uu->uu_softc;
|
||||
struct buf *bp;
|
||||
struct mscp_xi *mxi = uu->uu_ref;
|
||||
struct buf *bp = mxi->mxi_bp;
|
||||
int err;
|
||||
|
||||
while ((bp = sc->sc_bufq.sqh_first)) {
|
||||
if (ubaqueue(uu, bp)) {
|
||||
BUFQ_REMOVE_HEAD(&sc->sc_bufq, bp);
|
||||
mscp_dgo(sc->sc_softc, (UBAI_ADDR(uu->uu_ubinfo) |
|
||||
(UBAI_BDP(uu->uu_ubinfo) << 24)),uu->uu_ubinfo,bp);
|
||||
} else
|
||||
err = bus_dmamap_load(sc->sc_dmat, mxi->mxi_dmam, bp->b_un.b_addr,
|
||||
bp->b_bcount, bp->b_proc, BUS_DMA_NOWAIT);
|
||||
if (err)
|
||||
return 0;
|
||||
}
|
||||
mscp_dgo(sc->sc_softc, mxi);
|
||||
sc->sc_inq--;
|
||||
free(uu, M_DEVBUF);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -387,7 +408,7 @@ udasaerror(usc, doreset)
|
|||
int doreset;
|
||||
{
|
||||
struct uda_softc *sc = (void *)usc;
|
||||
register int code = sc->sc_udadev->udasa;
|
||||
register int code = bus_space_read_2(sc->sc_iot, sc->sc_sah, 0);
|
||||
register struct saerr *e;
|
||||
|
||||
if ((code & MP_ERR) == 0)
|
||||
|
@ -429,30 +450,28 @@ static void
|
|||
intr(sc)
|
||||
struct uda_softc *sc;
|
||||
{
|
||||
volatile struct udadevice *udaddr = sc->sc_udadev;
|
||||
struct uba_softc *uh;
|
||||
struct mscp_pack *ud;
|
||||
|
||||
#ifdef QBA
|
||||
if(vax_cputype == VAX_TYP_UV2)
|
||||
splx(sc->sc_ipl); /* Qbus interrupt protocol is odd */
|
||||
#endif
|
||||
sc->sc_wticks = 0; /* reset interrupt watchdog */
|
||||
|
||||
if (udaddr->udasa & MP_ERR) { /* ctlr fatal error */
|
||||
/* ctlr fatal error */
|
||||
if (bus_space_read_2(sc->sc_iot, sc->sc_sah, 0) & MP_ERR) {
|
||||
udasaerror(&sc->sc_dev, 1);
|
||||
return;
|
||||
}
|
||||
ud = &sc->sc_uda;
|
||||
/*
|
||||
* Handle buffer purge requests.
|
||||
* XXX - should be done in bus_dma_sync().
|
||||
*/
|
||||
uh = (void *)sc->sc_dev.dv_parent;
|
||||
if (ud->mp_ca.ca_bdp) {
|
||||
if (uh->uh_ubapurge)
|
||||
(*uh->uh_ubapurge)(uh, ud->mp_ca.ca_bdp);
|
||||
ud->mp_ca.ca_bdp = 0;
|
||||
udaddr->udasa = 0; /* signal purge complete */
|
||||
/* signal purge complete */
|
||||
bus_space_write_2(sc->sc_iot, sc->sc_sah, 0, 0);
|
||||
}
|
||||
|
||||
mscp_intr(sc->sc_softc);
|
||||
|
@ -488,11 +507,9 @@ reset(sc)
|
|||
* UDA50 is not yet initialised.
|
||||
*/
|
||||
if (sc->sc_unit.uu_bdp) {
|
||||
printf("<%d>", UBAI_BDP(sc->sc_unit.uu_bdp));
|
||||
/* printf("<%d>", UBAI_BDP(sc->sc_unit.uu_bdp)); */
|
||||
sc->sc_unit.uu_bdp = 0;
|
||||
}
|
||||
sc->sc_unit.uu_ubinfo = 0;
|
||||
/* sc->sc_unit.uu_cmd = 0; XXX */
|
||||
|
||||
/* reset queues and requeue pending transfers */
|
||||
mscp_requeue(sc->sc_softc);
|
||||
|
@ -508,13 +525,10 @@ reset(sc)
|
|||
}
|
||||
|
||||
void
|
||||
udactlrdone(usc, info)
|
||||
udactlrdone(usc)
|
||||
struct device *usc;
|
||||
int info;
|
||||
{
|
||||
struct uda_softc *sc = (void *)usc;
|
||||
|
||||
/* XXX check if we shall release the BDP */
|
||||
sc->sc_unit.uu_ubinfo = info;
|
||||
ubadone(&sc->sc_unit);
|
||||
uba_done((struct uba_softc *)sc->sc_dev.dv_parent);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue