Bus'ify the mscp code also.
This commit is contained in:
parent
a2692d780b
commit
508b5c5cee
@ -1,11 +1,11 @@
|
||||
# $NetBSD: files.mscp,v 1.6 1999/05/29 19:10:52 ragge Exp $
|
||||
# $NetBSD: files.mscp,v 1.7 1999/06/06 19:16:18 ragge Exp $
|
||||
#
|
||||
# File and device description for MSCP devices.
|
||||
#
|
||||
|
||||
define mscp {}
|
||||
file arch/vax/mscp/mscp.c mscp
|
||||
file arch/vax/mscp/mscp_subr.c mscp
|
||||
file dev/mscp/mscp.c mscp
|
||||
file dev/mscp/mscp_subr.c mscp
|
||||
|
||||
device mscpbus {drive = -1}
|
||||
attach mscpbus at mscp
|
||||
@ -15,9 +15,9 @@ attach rx at mscpbus
|
||||
|
||||
device ra: disk
|
||||
attach ra at mscpbus
|
||||
file arch/vax/mscp/mscp_disk.c ra | rx needs-flag
|
||||
file dev/mscp/mscp_disk.c ra | rx needs-flag
|
||||
|
||||
device mt: tape
|
||||
attach mt at mscpbus
|
||||
file arch/vax/mscp/mscp_tape.c mt needs-flag
|
||||
file dev/mscp/mscp_tape.c mt needs-flag
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mscp.c,v 1.10 1999/05/29 19:11:02 ragge Exp $ */
|
||||
/* $NetBSD: mscp.c,v 1.11 1999/06/06 19:16:18 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
|
||||
@ -50,16 +50,14 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <vax/mscp/mscp.h>
|
||||
#include <vax/mscp/mscpvar.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/mscp/mscp.h>
|
||||
#include <dev/mscp/mscpreg.h>
|
||||
#include <dev/mscp/mscpvar.h>
|
||||
|
||||
#define PCMD PSWP /* priority for command packet waits */
|
||||
|
||||
/*
|
||||
* During transfers, mapping info is saved in the buffer's b_resid.
|
||||
*/
|
||||
#define b_info b_resid
|
||||
|
||||
/*
|
||||
* Get a command packet. Second argument is true iff we are
|
||||
* to wait if necessary. Return NULL if none are available and
|
||||
@ -73,7 +71,7 @@ mscp_getcp(mi, canwait)
|
||||
#define mri (&mi->mi_cmd)
|
||||
register struct mscp *mp;
|
||||
register int i;
|
||||
int s = splbio();
|
||||
int s = splimp();
|
||||
|
||||
again:
|
||||
/*
|
||||
@ -136,10 +134,11 @@ mscp_dorsp(mi)
|
||||
struct device *drive;
|
||||
struct mscp_device *me = mi->mi_me;
|
||||
struct mscp_ctlr *mc = mi->mi_mc;
|
||||
register struct buf *bp;
|
||||
register struct mscp *mp;
|
||||
register int nextrsp;
|
||||
int st, error, info;
|
||||
struct buf *bp;
|
||||
struct mscp *mp;
|
||||
struct mscp_xi *mxi;
|
||||
int nextrsp;
|
||||
int st, error;
|
||||
extern int cold;
|
||||
extern struct mscp slavereply;
|
||||
|
||||
@ -310,22 +309,25 @@ loop:
|
||||
*/
|
||||
rwend:
|
||||
#ifdef DIAGNOSTIC
|
||||
if (mp->mscp_cmdref == 0) {
|
||||
if (mp->mscp_cmdref >= NCMD) {
|
||||
/*
|
||||
* No buffer means there is a bug somewhere!
|
||||
*/
|
||||
printf("%s: io done, but no buffer?\n",
|
||||
printf("%s: io done, but bad xfer number?\n",
|
||||
drive->dv_xname);
|
||||
mscp_hexdump(mp);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
bp = (struct buf *) mp->mscp_cmdref;
|
||||
|
||||
if (mp->mscp_cmdref == -1) {
|
||||
(*me->me_cmddone)(drive, mp);
|
||||
break;
|
||||
}
|
||||
mxi = &mi->mi_xi[mp->mscp_cmdref];
|
||||
if (mxi->mxi_inuse == 0)
|
||||
panic("mxi not inuse");
|
||||
bp = mxi->mxi_bp;
|
||||
/*
|
||||
* Mark any error-due-to-bad-LBN (via `goto rwend').
|
||||
* WHAT STATUS WILL THESE HAVE? IT SURE WOULD BE NICE
|
||||
@ -341,11 +343,6 @@ rwend:
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlink the transfer from the wait queue.
|
||||
*/
|
||||
_remque(&bp->b_actf);
|
||||
|
||||
/*
|
||||
* If the transfer has something to do with bad
|
||||
* block forwarding, let the driver handle the
|
||||
@ -381,12 +378,14 @@ rwend:
|
||||
* done. If the I/O wait queue is now empty, release
|
||||
* the shared BDP, if any.
|
||||
*/
|
||||
info = bp->b_info; /* we are about to clobber it */
|
||||
bp->b_resid = bp->b_bcount - mp->mscp_seq.seq_bytecount;
|
||||
bus_dmamap_unload(mi->mi_dmat, mxi->mxi_dmam);
|
||||
|
||||
(*mc->mc_ctlrdone)(mi->mi_dev.dv_parent, info);
|
||||
(*mc->mc_ctlrdone)(mi->mi_dev.dv_parent);
|
||||
(*me->me_iodone)(drive, bp);
|
||||
out:
|
||||
mxi->mxi_inuse = 0;
|
||||
mi->mi_mxiuse |= (1 << mp->mscp_cmdref);
|
||||
break;
|
||||
|
||||
case M_OP_REPLACE | M_OP_END:
|
||||
@ -422,12 +421,7 @@ unknown:
|
||||
*/
|
||||
#ifdef notyet /* XXX */
|
||||
if (ui->ui_flags & UNIT_REQUEUE) {
|
||||
bp = &md->md_utab[ui->ui_unit];
|
||||
if (bp->b_active) panic("mscp_dorsp requeue");
|
||||
MSCP_APPEND(bp, mi->mi_XXXtab, b_hash.le_next);
|
||||
/* Was: MSCP_APPEND(bp, mi->mi_XXXtab, b_forw); */
|
||||
bp->b_active = 1;
|
||||
ui->ui_flags &= ~UNIT_REQUEUE;
|
||||
...
|
||||
}
|
||||
#endif
|
||||
done:
|
||||
@ -449,69 +443,6 @@ void
|
||||
mscp_requeue(mi)
|
||||
struct mscp_softc *mi;
|
||||
{
|
||||
#if 0
|
||||
register struct mscp_device *me = mi->mi_me;
|
||||
register struct buf *bp, *dp;
|
||||
register int unit;
|
||||
struct buf *nextbp;
|
||||
#endif
|
||||
|
||||
panic("mscp_requeue");
|
||||
/*
|
||||
* Clear the controller chain. Mark everything un-busy; we
|
||||
* will soon fix any that are in fact busy.
|
||||
*/
|
||||
#ifdef notyet /* XXX */
|
||||
mi->mi_XXXtab->b_actf = NULL;
|
||||
mi->mi_XXXtab->b_active = 0;
|
||||
for (unit = 0, dp = md->md_utab; unit < md->md_nunits; unit++, dp++) {
|
||||
ui = md->md_dinfo[unit];
|
||||
if (ui == NULL || !ui->ui_alive || ui->ui_ctlr != mi->mi_ctlr)
|
||||
continue; /* not ours */
|
||||
dp->b_hash.le_next = NULL;
|
||||
dp->b_active = 0;
|
||||
}
|
||||
/*
|
||||
* Scan the wait queue, linking buffers onto drive queues.
|
||||
* Note that these must be put at the front of the drive queue,
|
||||
* lest we reorder I/O operations.
|
||||
*/
|
||||
for (bp = *mi->mi_XXXwtab.b_actb; bp != &mi->mi_XXXwtab; bp = nextbp) {
|
||||
nextbp = *bp->b_actb;
|
||||
dp = &md->md_utab[minor(bp->b_dev) >> md->md_unitshift];
|
||||
bp->b_actf = dp->b_actf;
|
||||
if (dp->b_actf == NULL)
|
||||
dp->b_actb = (void *)bp;
|
||||
dp->b_actf = bp;
|
||||
}
|
||||
mi->mi_XXXwtab.b_actf = *mi->mi_XXXwtab.b_actb = &mi->mi_XXXwtab;
|
||||
|
||||
/*
|
||||
* Scan for drives waiting for on line or status responses,
|
||||
* and for drives with pending transfers. Put these on the
|
||||
* controller queue, and mark the controller busy.
|
||||
*/
|
||||
for (unit = 0, dp = md->md_utab; unit < md->md_nunits; unit++, dp++) {
|
||||
ui = md->md_dinfo[unit];
|
||||
if (ui == NULL || !ui->ui_alive || ui->ui_ctlr != mi->mi_ctlr)
|
||||
continue;
|
||||
ui->ui_flags &= ~(UNIT_HAVESTATUS | UNIT_ONLINE);
|
||||
if ((ui->ui_flags & UNIT_REQUEUE) == 0 && dp->b_actf == NULL)
|
||||
continue;
|
||||
ui->ui_flags &= ~UNIT_REQUEUE;
|
||||
MSCP_APPEND(dp, mi->mi_XXXtab, b_hash.le_next);
|
||||
|
||||
dp->b_active = 1;
|
||||
mi->mi_XXXtab->b_active = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef AVOID_EMULEX_BUG
|
||||
/*
|
||||
* ... and clear the index-to-buffer table.
|
||||
*/
|
||||
for (unit = 0; unit < AEB_MAX_BP; unit++)
|
||||
mi->mi_bp[unit] = 0;
|
||||
#endif
|
||||
panic("mscp_requeue");
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mscp_disk.c,v 1.20 1999/05/29 19:11:41 ragge Exp $ */
|
||||
/* $NetBSD: mscp_disk.c,v 1.21 1999/06/06 19:16:18 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
@ -63,11 +63,13 @@
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/rpb.h>
|
||||
|
||||
#include <vax/mscp/mscp.h>
|
||||
#include <vax/mscp/mscpvar.h>
|
||||
#include <dev/mscp/mscp.h>
|
||||
#include <dev/mscp/mscpreg.h>
|
||||
#include <dev/mscp/mscpvar.h>
|
||||
|
||||
#include "locators.h"
|
||||
#include "ioconf.h"
|
||||
@ -285,7 +287,7 @@ raclose(dev, flags, fmt, p)
|
||||
*/
|
||||
#if notyet
|
||||
if (ra->ra_openpart == 0) {
|
||||
s = splbio();
|
||||
s = splimp();
|
||||
while (udautab[unit].b_actf)
|
||||
sleep((caddr_t)&udautab[unit], PZERO - 1);
|
||||
splx(s);
|
||||
@ -579,7 +581,7 @@ rx_putonline(rx)
|
||||
*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
|
||||
|
||||
/* Poll away */
|
||||
i = *mi->mi_ip;
|
||||
i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
|
||||
if (tsleep(&rx->ra_dev.dv_unit, PRIBIO, "rxonline", 100*100))
|
||||
rx->ra_state = DK_CLOSED;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mscp_subr.c,v 1.11 1999/05/29 19:11:52 ragge Exp $ */
|
||||
/* $NetBSD: mscp_subr.c,v 1.12 1999/06/06 19:16:18 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
@ -48,11 +48,12 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/sid.h>
|
||||
|
||||
#include <vax/mscp/mscp.h>
|
||||
#include <vax/mscp/mscpreg.h>
|
||||
#include <vax/mscp/mscpvar.h>
|
||||
#include <dev/mscp/mscp.h>
|
||||
#include <dev/mscp/mscpreg.h>
|
||||
#include <dev/mscp/mscpvar.h>
|
||||
|
||||
#include "ra.h"
|
||||
#include "mt.h"
|
||||
@ -70,6 +71,11 @@ struct cfattach mscpbus_ca = {
|
||||
sizeof(struct mscp_softc), mscp_match, mscp_attach
|
||||
};
|
||||
|
||||
#define READ_SA (bus_space_read_2(mi->mi_iot, mi->mi_sah, 0))
|
||||
#define READ_IP (bus_space_read_2(mi->mi_iot, mi->mi_iph, 0))
|
||||
#define WRITE_IP(x) bus_space_write_2(mi->mi_iot, mi->mi_iph, 0, (x))
|
||||
#define WRITE_SW(x) bus_space_write_2(mi->mi_iot, mi->mi_swh, 0, (x))
|
||||
|
||||
struct mscp slavereply;
|
||||
|
||||
/*
|
||||
@ -86,9 +92,9 @@ mscp_waitstep(mi, mask, result)
|
||||
{
|
||||
int status = 1;
|
||||
|
||||
if ((*mi->mi_sa & mask) != result) {
|
||||
if ((READ_SA & mask) != result) {
|
||||
volatile int count = 0;
|
||||
while ((*mi->mi_sa & mask) != result) {
|
||||
while ((READ_SA & mask) != result) {
|
||||
DELAY(10000);
|
||||
count += 1;
|
||||
if (count > DELAYTEN)
|
||||
@ -133,11 +139,13 @@ mscp_attach(parent, self, aux)
|
||||
mi->mi_mc = ma->ma_mc;
|
||||
mi->mi_me = NULL;
|
||||
mi->mi_type = ma->ma_type;
|
||||
mi->mi_uuda = ma->ma_uuda;
|
||||
mi->mi_uda = ma->ma_uda;
|
||||
mi->mi_ip = ma->ma_ip;
|
||||
mi->mi_sa = ma->ma_sa;
|
||||
mi->mi_sw = ma->ma_sw;
|
||||
mi->mi_dmat = ma->ma_dmat;
|
||||
mi->mi_dmam = ma->ma_dmam;
|
||||
mi->mi_iot = ma->ma_iot;
|
||||
mi->mi_iph = ma->ma_iph;
|
||||
mi->mi_sah = ma->ma_sah;
|
||||
mi->mi_swh = ma->ma_swh;
|
||||
mi->mi_ivec = ma->ma_ivec;
|
||||
mi->mi_adapnr = ma->ma_adapnr;
|
||||
mi->mi_ctlrnr = ma->ma_ctlrnr;
|
||||
@ -152,14 +160,22 @@ mscp_attach(parent, self, aux)
|
||||
mi->mi_rsp.mri_size = NRSP;
|
||||
mi->mi_rsp.mri_desc = mi->mi_uda->mp_ca.ca_rspdsc;
|
||||
mi->mi_rsp.mri_ring = mi->mi_uda->mp_rsp;
|
||||
mi->mi_actf = (void *)&mi->mi_actf; /* Circular wait queue */
|
||||
mi->mi_actb = (void *)&mi->mi_actf;
|
||||
SIMPLEQ_INIT(&mi->mi_resq);
|
||||
|
||||
if (mscp_init(mi)) {
|
||||
printf("%s: can't init, controller hung\n",
|
||||
mi->mi_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < NCMD; i++) {
|
||||
mi->mi_mxiuse |= (1 << i);
|
||||
if (bus_dmamap_create(mi->mi_dmat, (64*1024), 1, (64*1024),
|
||||
0, BUS_DMA_NOWAIT, &mi->mi_xi[i].mxi_dmam)) {
|
||||
printf("Couldn't alloc dmamap %d\n", i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if NRA
|
||||
if (ma->ma_type & MSCPBUS_DISK) {
|
||||
@ -189,7 +205,7 @@ findunit:
|
||||
*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
|
||||
slavereply.mscp_opcode = 0;
|
||||
|
||||
i = *mi->mi_ip; /* Kick off polling */
|
||||
i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
|
||||
mp = &slavereply;
|
||||
timeout = 1000;
|
||||
while (timeout-- > 0) {
|
||||
@ -295,19 +311,19 @@ mscp_init(mi)
|
||||
mi->mi_flags |= MSC_IGNOREINTR;
|
||||
|
||||
if ((mi->mi_type & MSCPBUS_KDB) == 0)
|
||||
*mi->mi_ip = 0; /* Kick off */
|
||||
WRITE_IP(0); /* Kick off */;
|
||||
|
||||
status = mscp_waitstep(mi, MP_STEP1, MP_STEP1);/* Wait to it wakes up */
|
||||
if (status == 0)
|
||||
return 1; /* Init failed */
|
||||
if (*mi->mi_sa & MP_ERR) {
|
||||
if (READ_SA & MP_ERR) {
|
||||
(*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* step1 */
|
||||
*mi->mi_sw = MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) |
|
||||
MP_IE | (mi->mi_ivec >> 2);
|
||||
WRITE_SW(MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) |
|
||||
MP_IE | (mi->mi_ivec >> 2));
|
||||
status = mscp_waitstep(mi, STEP1MASK, STEP1GOOD);
|
||||
if (status == 0) {
|
||||
(*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0);
|
||||
@ -315,8 +331,9 @@ mscp_init(mi)
|
||||
}
|
||||
|
||||
/* step2 */
|
||||
*mi->mi_sw = (int)&mi->mi_uuda->mp_ca.ca_rspdsc[0] |
|
||||
(vax_cputype == VAX_780 || vax_cputype == VAX_8600 ? MP_PI : 0);
|
||||
WRITE_SW(((mi->mi_dmam->dm_segs[0].ds_addr & 0xffff) +
|
||||
offsetof(struct mscp_pack, mp_ca.ca_rspdsc[0])) |
|
||||
(vax_cputype == VAX_780 || vax_cputype == VAX_8600 ? MP_PI : 0));
|
||||
status = mscp_waitstep(mi, STEP2MASK, STEP2GOOD(mi->mi_ivec >> 2));
|
||||
if (status == 0) {
|
||||
(*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0);
|
||||
@ -324,22 +341,23 @@ mscp_init(mi)
|
||||
}
|
||||
|
||||
/* step3 */
|
||||
*mi->mi_sw = ((int)&mi->mi_uuda->mp_ca.ca_rspdsc[0]) >> 16;
|
||||
|
||||
WRITE_SW((mi->mi_dmam->dm_segs[0].ds_addr >> 16));
|
||||
status = mscp_waitstep(mi, STEP3MASK, STEP3GOOD);
|
||||
if (status == 0) {
|
||||
(*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0);
|
||||
return 1;
|
||||
}
|
||||
i = *mi->mi_sa & 0377;
|
||||
i = READ_SA & 0377;
|
||||
printf(": version %d model %d\n", i & 15, i >> 4);
|
||||
|
||||
#define BURST 4 /* XXX */
|
||||
if (mi->mi_type & MSCPBUS_UDA) {
|
||||
*mi->mi_sw = MP_GO | (BURST - 1) << 2;
|
||||
WRITE_SW(MP_GO | (BURST - 1) << 2);
|
||||
printf("%s: DMA burst size set to %d\n",
|
||||
mi->mi_dev.dv_xname, BURST);
|
||||
}
|
||||
*mi->mi_sw = MP_GO;
|
||||
WRITE_SW(MP_GO);
|
||||
|
||||
mscp_initds(mi);
|
||||
mi->mi_flags &= ~MSC_IGNOREINTR;
|
||||
@ -359,13 +377,13 @@ mscp_init(mi)
|
||||
mp->mscp_sccc.sccc_errlgfl = 0;
|
||||
mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | M_CF_THIS;
|
||||
*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
|
||||
i = *mi->mi_ip;
|
||||
i = READ_IP;
|
||||
|
||||
count = 0;
|
||||
while (count < DELAYTEN) {
|
||||
if (((volatile int)mi->mi_flags & MSC_READY) != 0)
|
||||
break;
|
||||
if ((j = *mi->mi_sa) & MP_ERR)
|
||||
if ((j = READ_SA) & MP_ERR)
|
||||
goto out;
|
||||
DELAY(10000);
|
||||
count += 1;
|
||||
@ -386,20 +404,21 @@ void
|
||||
mscp_initds(mi)
|
||||
struct mscp_softc *mi;
|
||||
{
|
||||
struct mscp_pack *uud = mi->mi_uuda;
|
||||
struct mscp_pack *ud = mi->mi_uda;
|
||||
struct mscp *mp;
|
||||
int i;
|
||||
|
||||
for (i = 0, mp = ud->mp_rsp; i < NRSP; i++, mp++) {
|
||||
ud->mp_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT |
|
||||
(long)&uud->mp_rsp[i].mscp_cmdref;
|
||||
(mi->mi_dmam->dm_segs[0].ds_addr +
|
||||
offsetof(struct mscp_pack, mp_rsp[i].mscp_cmdref));
|
||||
mp->mscp_addr = &ud->mp_ca.ca_rspdsc[i];
|
||||
mp->mscp_msglen = MSCP_MSGLEN;
|
||||
}
|
||||
for (i = 0, mp = ud->mp_cmd; i < NCMD; i++, mp++) {
|
||||
ud->mp_ca.ca_cmddsc[i] = MSCP_INT |
|
||||
(long)&uud->mp_cmd[i].mscp_cmdref;
|
||||
(mi->mi_dmam->dm_segs[0].ds_addr +
|
||||
offsetof(struct mscp_pack, mp_cmd[i].mscp_cmdref));
|
||||
mp->mscp_addr = &ud->mp_ca.ca_cmddsc[i];
|
||||
mp->mscp_msglen = MSCP_MSGLEN;
|
||||
if (mi->mi_type & MSCPBUS_TAPE)
|
||||
@ -407,6 +426,8 @@ mscp_initds(mi)
|
||||
}
|
||||
}
|
||||
|
||||
static void mscp_kickaway(struct mscp_softc *);
|
||||
|
||||
void
|
||||
mscp_intr(mi)
|
||||
struct mscp_softc *mi;
|
||||
@ -428,18 +449,10 @@ mscp_intr(mi)
|
||||
}
|
||||
|
||||
/*
|
||||
* If there are any not-yet-handled requeset, try them now.
|
||||
* XXX - We handles them (erroneous) in last-in first-handled order.
|
||||
* Must we fix this???
|
||||
* If there are any not-yet-handled request, try them now.
|
||||
*/
|
||||
while (mi->mi_w) {
|
||||
struct buf *bp = mi->mi_w;
|
||||
|
||||
mi->mi_w = (void *)bp->b_actb;
|
||||
mscp_strategy(bp, (struct device *)mi);
|
||||
if (mi->mi_w == bp)
|
||||
break;
|
||||
}
|
||||
if (SIMPLEQ_FIRST(&mi->mi_resq))
|
||||
mscp_kickaway(mi);
|
||||
}
|
||||
|
||||
int
|
||||
@ -463,7 +476,6 @@ mscp_print(aux, name)
|
||||
|
||||
/*
|
||||
* common strategy routine for all types of MSCP devices.
|
||||
* bp is the current buf, dp is the drive queue.
|
||||
*/
|
||||
void
|
||||
mscp_strategy(bp, usc)
|
||||
@ -471,42 +483,70 @@ mscp_strategy(bp, usc)
|
||||
struct device *usc;
|
||||
{
|
||||
struct mscp_softc *mi = (void *)usc;
|
||||
struct mscp *mp;
|
||||
int s = spl6();
|
||||
int s = splimp();
|
||||
|
||||
/*
|
||||
* Ok; we are ready to try to start a xfer. Get a MSCP packet
|
||||
* and try to start...
|
||||
*/
|
||||
if ((mp = mscp_getcp(mi, MSCP_DONTWAIT)) == NULL) {
|
||||
if (mi->mi_credits > MSCP_MINCREDITS)
|
||||
printf("%s: command ring too small\n",
|
||||
mi->mi_dev.dv_parent->dv_xname);
|
||||
/*
|
||||
* By some (strange) reason we didn't get a MSCP packet.
|
||||
* Put it on queue and wait for free packets.
|
||||
*/
|
||||
(void *)bp->b_actb = mi->mi_w;
|
||||
mi->mi_w = bp;
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the MSCP packet and ask the ctlr to start.
|
||||
*/
|
||||
mp->mscp_opcode = (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
|
||||
(*mi->mi_me->me_fillin)(bp, mp);
|
||||
(void *)bp->b_actb = mp; /* b_actb is unused, save mscp packet here */
|
||||
(*mi->mi_mc->mc_go)(mi->mi_dev.dv_parent, bp);
|
||||
/* SIMPLEQ_INSERT_TAIL(&mi->mi_resq, bp, xxx) */
|
||||
bp->b_actf = NULL;
|
||||
*mi->mi_resq.sqh_last = bp;
|
||||
mi->mi_resq.sqh_last = &bp->b_actf;
|
||||
mscp_kickaway(mi);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mscp_dgo(mi, buffer, info, bp)
|
||||
struct mscp_softc *mi;
|
||||
long buffer, info;
|
||||
mscp_kickaway(mi)
|
||||
struct mscp_softc *mi;
|
||||
{
|
||||
struct buf *bp;
|
||||
struct mscp *mp;
|
||||
int next;
|
||||
|
||||
while ((bp = SIMPLEQ_FIRST(&mi->mi_resq))) {
|
||||
/*
|
||||
* Ok; we are ready to try to start a xfer. Get a MSCP packet
|
||||
* and try to start...
|
||||
*/
|
||||
if ((mp = mscp_getcp(mi, MSCP_DONTWAIT)) == NULL) {
|
||||
if (mi->mi_credits > MSCP_MINCREDITS)
|
||||
printf("%s: command ring too small\n",
|
||||
mi->mi_dev.dv_parent->dv_xname);
|
||||
/*
|
||||
* By some (strange) reason we didn't get a MSCP packet.
|
||||
* Just return and wait for free packets.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if ((next = (ffs(mi->mi_mxiuse) - 1)) < 0)
|
||||
panic("no mxi buffers");
|
||||
mi->mi_mxiuse &= ~(1 << next);
|
||||
if (mi->mi_xi[next].mxi_inuse)
|
||||
panic("mxi inuse");
|
||||
/*
|
||||
* Set up the MSCP packet and ask the ctlr to start.
|
||||
*/
|
||||
mp->mscp_opcode =
|
||||
(bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
|
||||
mp->mscp_cmdref = next;
|
||||
mi->mi_xi[next].mxi_bp = bp;
|
||||
mi->mi_xi[next].mxi_mp = mp;
|
||||
mi->mi_xi[next].mxi_inuse = 1;
|
||||
bp->b_resid = next;
|
||||
(*mi->mi_me->me_fillin)(bp, mp);
|
||||
(*mi->mi_mc->mc_go)(mi->mi_dev.dv_parent, &mi->mi_xi[next]);
|
||||
if ((mi->mi_resq.sqh_first = bp->b_actf) == NULL)
|
||||
mi->mi_resq.sqh_last = &mi->mi_resq.sqh_first;
|
||||
#if 0
|
||||
mi->mi_w = bp->b_actf;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mscp_dgo(mi, mxi)
|
||||
struct mscp_softc *mi;
|
||||
struct mscp_xi *mxi;
|
||||
{
|
||||
volatile int i;
|
||||
struct mscp *mp;
|
||||
@ -514,17 +554,11 @@ mscp_dgo(mi, buffer, info, bp)
|
||||
/*
|
||||
* Fill in the MSCP packet and move the buffer to the I/O wait queue.
|
||||
*/
|
||||
mp = (void *)bp->b_actb;
|
||||
mp = mxi->mxi_mp;
|
||||
mp->mscp_seq.seq_buffer = mxi->mxi_dmam->dm_segs[0].ds_addr;
|
||||
|
||||
mp->mscp_seq.seq_buffer = buffer;
|
||||
|
||||
_insque(&bp->b_actf, &mi->mi_actf);
|
||||
|
||||
bp->b_resid = info;
|
||||
mp->mscp_cmdref = (long) bp;
|
||||
*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
|
||||
|
||||
i = *mi->mi_ip;
|
||||
i = READ_IP;
|
||||
}
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mscp_tape.c,v 1.13 1999/05/29 19:12:42 ragge Exp $ */
|
||||
/* $NetBSD: mscp_tape.c,v 1.14 1999/06/06 19:16:18 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
|
||||
* All rights reserved.
|
||||
@ -51,10 +51,12 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <vax/mscp/mscp.h>
|
||||
#include <vax/mscp/mscpvar.h>
|
||||
#include <dev/mscp/mscp.h>
|
||||
#include <dev/mscp/mscpreg.h>
|
||||
#include <dev/mscp/mscpvar.h>
|
||||
|
||||
#include "locators.h"
|
||||
|
||||
@ -176,7 +178,7 @@ mt_putonline(mt)
|
||||
*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
|
||||
|
||||
/* Poll away */
|
||||
i = *mi->mi_ip;
|
||||
i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
|
||||
if (tsleep(&mt->mt_state, PRIBIO, "mtonline", 240 * hz))
|
||||
return MSCP_FAILED;
|
||||
|
||||
@ -542,7 +544,7 @@ mtcmd(mt, cmd, count, complete)
|
||||
break;
|
||||
}
|
||||
|
||||
i = *mi->mi_ip;
|
||||
i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
|
||||
tsleep(&mt->mt_inuse, PRIBIO, "mtioctl", 0);
|
||||
return mt->mt_ioctlerr;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mscpvar.h,v 1.6 1999/05/29 19:13:04 ragge Exp $ */
|
||||
/* $NetBSD: mscpvar.h,v 1.7 1999/06/06 19:16:18 ragge Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
@ -69,11 +69,21 @@ struct mscp_ri {
|
||||
struct mscp *mri_ring; /* base address of packets */
|
||||
};
|
||||
|
||||
/*
|
||||
* Transfer info, one per command packet.
|
||||
*/
|
||||
struct mscp_xi {
|
||||
bus_dmamap_t mxi_dmam; /* Allocated DMA map for this entry */
|
||||
struct buf * mxi_bp; /* Buffer used in this command */
|
||||
struct mscp * mxi_mp; /* Packet used in this command */
|
||||
int mxi_inuse;
|
||||
};
|
||||
|
||||
struct mscp_ctlr {
|
||||
void (*mc_ctlrdone) /* controller operation complete */
|
||||
__P((struct device *, int));
|
||||
int (*mc_go) /* device-specific start routine */
|
||||
__P((struct device *, struct buf *));
|
||||
__P((struct device *));
|
||||
void (*mc_go) /* device-specific start routine */
|
||||
__P((struct device *, struct mscp_xi *));
|
||||
void (*mc_saerror) /* ctlr error handling */
|
||||
__P((struct device *, int));
|
||||
};
|
||||
@ -108,11 +118,13 @@ struct mscp_attach_args {
|
||||
struct mscp_ctlr *ma_mc; /* Pointer to ctlr's mscp_ctlr */
|
||||
int ma_type; /* disk/tape bus type */
|
||||
struct mscp_pack *ma_uda; /* comm area virtual */
|
||||
struct mscp_pack *ma_uuda; /* comm area on bus */
|
||||
struct mscp_softc **ma_softc; /* backpointer to bus softc */
|
||||
short *ma_ip; /* initialisation and polling */
|
||||
short *ma_sa; /* status & address (read part) */
|
||||
short *ma_sw; /* status & address (write part) */
|
||||
bus_dmamap_t ma_dmam; /* This comm area dma info */
|
||||
bus_dma_tag_t ma_dmat;
|
||||
bus_space_tag_t ma_iot;
|
||||
bus_space_handle_t ma_iph; /* initialisation and polling */
|
||||
bus_space_handle_t ma_sah; /* status & address (read part) */
|
||||
bus_space_handle_t ma_swh; /* status & address (write part) */
|
||||
short ma_ivec; /* Interrupt vector to use */
|
||||
char ma_ctlrnr; /* Phys ctlr nr */
|
||||
char ma_adapnr; /* Phys adapter nr */
|
||||
@ -157,11 +169,13 @@ struct mscp_softc {
|
||||
struct device mi_dev; /* Autoconf stuff */
|
||||
struct mscp_ri mi_cmd; /* MSCP command ring info */
|
||||
struct mscp_ri mi_rsp; /* MSCP response ring info */
|
||||
bus_dma_tag_t mi_dmat;
|
||||
bus_dmamap_t mi_dmam;
|
||||
struct mscp_xi mi_xi[NCMD];
|
||||
int mi_mxiuse; /* Bitfield of inuse mxi packets */
|
||||
short mi_credits; /* transfer credits */
|
||||
char mi_wantcmd; /* waiting for command packet */
|
||||
char mi_wantcredits; /* waiting for transfer credits */
|
||||
struct buf *mi_actf; /* Pointer to buffers in */
|
||||
struct buf *mi_actb; /* circular wait queue */
|
||||
struct mscp_ctlr *mi_mc; /* Pointer to parent's mscp_ctlr */
|
||||
struct mscp_device *mi_me; /* Pointer to child's mscp_device */
|
||||
struct device **mi_dp; /* array of backpointers */
|
||||
@ -170,14 +184,14 @@ struct mscp_softc {
|
||||
char mi_adapnr; /* Phys adapter nr */
|
||||
int mi_flags;
|
||||
struct mscp_pack *mi_uda; /* virtual address */
|
||||
struct mscp_pack *mi_uuda; /* (device-specific) address */
|
||||
int mi_type;
|
||||
short mi_ivec; /* Interrupt vector to use */
|
||||
short mi_ierr; /* Init err counter */
|
||||
volatile short *mi_ip; /* initialisation and polling */
|
||||
volatile short *mi_sa; /* status & address (read part) */
|
||||
volatile short *mi_sw; /* status & address (write part) */
|
||||
struct buf *mi_w; /* While waiting for packets */
|
||||
bus_space_tag_t mi_iot;
|
||||
bus_space_handle_t mi_iph; /* initialisation and polling */
|
||||
bus_space_handle_t mi_sah; /* status & address (read part) */
|
||||
bus_space_handle_t mi_swh; /* status & address (write part) */
|
||||
SIMPLEQ_HEAD(, buf) mi_resq; /* While waiting for packets */
|
||||
};
|
||||
|
||||
/* mi_flags */
|
||||
@ -220,24 +234,6 @@ struct mscp_softc {
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* The following macro appends a buffer to a drive queue or a drive to
|
||||
* a controller queue, given the name of the forward link. Use as
|
||||
* `APPEND(dp, &um->um_tab, b_forw)' or `APPEND(bp, dp, av_forw)',
|
||||
* where `bp' is a transfer request, `dp' is a drive queue, and `um_tab'
|
||||
* is a controller queue. (That is, the forward link for controller
|
||||
* queues is `b_forw'; for drive queues, it is `av_forw'.)
|
||||
*/
|
||||
|
||||
#define MSCP_APPEND(bp, queue, link) { \
|
||||
(bp)->link = NULL; \
|
||||
if ((queue)->link == NULL) \
|
||||
(queue)->link = (bp); \
|
||||
else \
|
||||
*(queue)->b_actb = (bp); \
|
||||
(queue)->b_actb = &(bp)->link; \
|
||||
}
|
||||
|
||||
/* Prototypes */
|
||||
struct mscp *mscp_getcp __P((struct mscp_softc *, int));
|
||||
void mscp_printevent __P((struct mscp *));
|
||||
@ -250,5 +246,5 @@ void mscp_hexdump __P((struct mscp *));
|
||||
void mscp_strategy __P((struct buf *, struct device *));
|
||||
void mscp_printtype __P((int, int));
|
||||
int mscp_waitstep __P((struct mscp_softc *, int, int));
|
||||
void mscp_dgo __P((struct mscp_softc *, long, long, struct buf *));
|
||||
void mscp_dgo __P((struct mscp_softc *, struct mscp_xi *));
|
||||
void mscp_intr __P((struct mscp_softc *));
|
||||
|
Loading…
Reference in New Issue
Block a user