Split sii driver into bus-dependent front-end and chip-specific back-end:
sii_ds.c -- front-end for Decstation 2100, 3100, 5100(?) sii.c -- driver for DEC scsi asic used in decstations and vax 3400s siivar.h -- shared softc
This commit is contained in:
parent
de83b4558f
commit
986daa1436
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sii.c,v 1.16 1996/10/11 00:44:58 christos Exp $ */
|
||||
/* $NetBSD: sii.c,v 1.17 1996/10/13 03:02:39 jonathan Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -64,70 +64,31 @@
|
|||
#include <pmax/dev/device.h>
|
||||
#include <pmax/dev/scsi.h>
|
||||
#include <pmax/dev/siireg.h>
|
||||
#include <pmax/dev/siivar.h>
|
||||
|
||||
#include <pmax/pmax/kn01.h>
|
||||
|
||||
typedef struct scsi_state {
|
||||
int statusByte; /* status byte returned during STATUS_PHASE */
|
||||
int dmaDataPhase; /* which data phase to expect */
|
||||
int dmaCurPhase; /* SCSI phase if DMA is in progress */
|
||||
int dmaPrevPhase; /* SCSI phase of DMA suspended by disconnect */
|
||||
u_short *dmaAddr[2]; /* DMA buffer memory address */
|
||||
int dmaBufIndex; /* which of the above is currently in use */
|
||||
int dmalen; /* amount to transfer in this chunk */
|
||||
int cmdlen; /* total remaining amount of cmd to transfer */
|
||||
u_char *cmd; /* current pointer within scsicmd->cmd */
|
||||
int buflen; /* total remaining amount of data to transfer */
|
||||
char *buf; /* current pointer within scsicmd->buf */
|
||||
u_short flags; /* see below */
|
||||
u_short prevComm; /* command reg before disconnect */
|
||||
u_short dmaCtrl; /* DMA control register if disconnect */
|
||||
u_short dmaAddrL; /* DMA address register if disconnect */
|
||||
u_short dmaAddrH; /* DMA address register if disconnect */
|
||||
u_short dmaCnt; /* DMA count if disconnect */
|
||||
u_short dmaByte; /* DMA byte if disconnect on odd boundary */
|
||||
u_short dmaReqAck; /* DMA synchronous xfer offset or 0 if async */
|
||||
} State;
|
||||
|
||||
/* state flags */
|
||||
#define FIRST_DMA 0x01 /* true if no data DMA started yet */
|
||||
#define PARITY_ERR 0x02 /* true if parity error seen */
|
||||
|
||||
#define SII_NCMD 7
|
||||
struct siisoftc {
|
||||
struct device sc_dev; /* us as a device */
|
||||
SIIRegs *sc_regs; /* HW address of SII controller chip */
|
||||
int sc_flags;
|
||||
int sc_target; /* target SCSI ID if connected */
|
||||
ScsiCmd *sc_cmd[SII_NCMD]; /* active command indexed by ID */
|
||||
State sc_st[SII_NCMD]; /* state info for each active command */
|
||||
#ifdef NEW_SCSI
|
||||
struct scsi_link sc_link; /* scsi lint struct */
|
||||
#endif
|
||||
};
|
||||
/* Machine-indepedent back-end attach entry point */
|
||||
void siiattach __P((struct siisoftc *sc));
|
||||
|
||||
/*
|
||||
* Device definition for autoconfiguration.
|
||||
*
|
||||
* Autoconfig definition of driver front-end
|
||||
*/
|
||||
int siimatch __P((struct device * parent, void *cfdata, void *aux));
|
||||
void siiattach __P((struct device *parent, struct device *self, void *aux));
|
||||
int siiprint(void*, char*);
|
||||
|
||||
int sii_doprobe __P((void *addr, int unit, int flags, int pri,
|
||||
struct device *self));
|
||||
int siiintr __P((void *sc));
|
||||
|
||||
extern struct cfdriver sii_cd;
|
||||
int old_siimatch __P((struct device * parent, void *cfdata, void *aux));
|
||||
void old_siiattach __P((struct device *parent, struct device *self, void *aux));
|
||||
|
||||
extern struct cfattach sii_ca;
|
||||
struct cfattach sii_ca = {
|
||||
sizeof(struct siisoftc), siimatch, siiattach
|
||||
sizeof(struct siisoftc), old_siimatch, old_siiattach
|
||||
};
|
||||
|
||||
extern struct cfdriver sii_cd;
|
||||
struct cfdriver sii_cd = {
|
||||
NULL, "sii", DV_DULL
|
||||
};
|
||||
|
||||
int siiprint(void*, char*);
|
||||
int siiintr __P((void *sc));
|
||||
|
||||
#ifdef USE_NEW_SCSI
|
||||
/* Glue to the machine-independent scsi */
|
||||
struct scsi_adapter asc_switch = {
|
||||
|
@ -202,10 +163,12 @@ u_char sii_buf[256]; /* used for extended messages */
|
|||
#define NOWAIT 0
|
||||
#define WAIT 1
|
||||
|
||||
/* define a safe address in the SCSI buffer for doing status & message DMA */
|
||||
#define SII_BUF_ADDR (MACH_PHYS_TO_UNCACHED(KN01_SYS_SII_B_START) \
|
||||
+ SII_MAX_DMA_XFER_LENGTH * 14)
|
||||
|
||||
/*
|
||||
* Define a safe address in the SCSI buffer for doing status & message DMA
|
||||
* XXX why not add another field to softc?
|
||||
*/
|
||||
#define SII_BUF_ADDR(sc) ((sc)->sc_buf + SII_MAX_DMA_XFER_LENGTH * 14)
|
||||
|
||||
/*
|
||||
* Other forward references
|
||||
|
@ -243,7 +206,7 @@ struct pmax_driver siidriver = {
|
|||
* Match driver based on name
|
||||
*/
|
||||
int
|
||||
siimatch(parent, match, aux)
|
||||
old_siimatch(parent, match, aux)
|
||||
struct device *parent;
|
||||
void *match;
|
||||
void *aux;
|
||||
|
@ -266,21 +229,31 @@ siimatch(parent, match, aux)
|
|||
}
|
||||
|
||||
void
|
||||
siiattach(parent, self, aux)
|
||||
old_siiattach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
{
|
||||
register struct confargs *ca = aux;
|
||||
register struct siisoftc *sc = (struct siisoftc *) self;
|
||||
register void *siiaddr;
|
||||
register int i;
|
||||
|
||||
siiaddr = (void*)MACH_PHYS_TO_UNCACHED(ca->ca_addr);
|
||||
|
||||
sc->sc_regs = (SIIRegs *)siiaddr;
|
||||
sc->sc_regs = (SIIRegs *)MACH_PHYS_TO_UNCACHED(ca->ca_addr);
|
||||
sc->sc_flags = sc->sc_dev.dv_cfdata->cf_flags;
|
||||
sc->sc_target = -1; /* no command active */
|
||||
|
||||
siiattach(sc);
|
||||
|
||||
/* tie pseudo-slot to device */
|
||||
BUS_INTR_ESTABLISH(ca, siiintr, sc);
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
siiattach(sc)
|
||||
register struct siisoftc *sc;
|
||||
{
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* Give each target its own DMA buffer region.
|
||||
* Make it big enough for 2 max transfers so we can ping pong buffers
|
||||
|
@ -288,8 +261,7 @@ siiattach(parent, self, aux)
|
|||
*/
|
||||
for (i = 0; i < SII_NCMD; i++) {
|
||||
sc->sc_st[i].dmaAddr[0] = (u_short *)
|
||||
MACH_PHYS_TO_UNCACHED(KN01_SYS_SII_B_START) +
|
||||
2 * SII_MAX_DMA_XFER_LENGTH * i;
|
||||
sc->sc_buf + 2 * SII_MAX_DMA_XFER_LENGTH * i;
|
||||
sc->sc_st[i].dmaAddr[1] = sc->sc_st[i].dmaAddr[0] +
|
||||
SII_MAX_DMA_XFER_LENGTH;
|
||||
}
|
||||
|
@ -298,13 +270,13 @@ siiattach(parent, self, aux)
|
|||
(void) pmax_add_scsi(&siidriver, sc->sc_dev.dv_unit);
|
||||
|
||||
sii_Reset(sc, RESET);
|
||||
|
||||
/*priority = ca->ca_slot;*/
|
||||
/* tie pseudo-slot to device */
|
||||
BUS_INTR_ESTABLISH(ca, siiintr, sc);
|
||||
kprintf("\n");
|
||||
#ifdef USE_NEW_SCSI
|
||||
/* XXX probe SCSI bus and attach slave devices */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Start activity on a SCSI device.
|
||||
* We maintain information on each device separately since devices can
|
||||
|
@ -517,11 +489,11 @@ sii_StartCmd(sc, target)
|
|||
state->dmaCurPhase = SII_MSG_OUT_PHASE,
|
||||
state->dmalen = 6;
|
||||
CopyToBuffer((u_short *)sii_buf,
|
||||
(volatile u_short *)SII_BUF_ADDR, 6);
|
||||
(volatile u_short *)SII_BUF_ADDR(sc), 6);
|
||||
regs->slcsr = target;
|
||||
regs->dmctrl = state->dmaReqAck;
|
||||
regs->dmaddrl = (u_short)(SII_BUF_ADDR >> 1);
|
||||
regs->dmaddrh = (u_short)(SII_BUF_ADDR >> 17) & 03;
|
||||
regs->dmaddrl = (u_short)(SII_BUF_ADDR(sc) >> 1);
|
||||
regs->dmaddrh = (u_short)(SII_BUF_ADDR(sc) >> 17) & 03;
|
||||
regs->dmlotc = 6;
|
||||
regs->comm = SII_DMA | SII_INXFER | SII_SELECT | SII_ATN |
|
||||
SII_CON | SII_MSG_OUT_PHASE;
|
||||
|
@ -1747,15 +1719,16 @@ sii_DoSync(regs, state)
|
|||
regs->dstat = SII_DNE;
|
||||
wbflush();
|
||||
}
|
||||
#else
|
||||
CopyToBuffer((u_short *)sii_buf, (volatile u_short *)SII_BUF_ADDR, 5);
|
||||
#else /* 0 */
|
||||
CopyToBuffer((u_short *)sii_buf,
|
||||
(volatile u_short *)SII_BUF_ADDR(sc), 5);
|
||||
kprintf("sii_DoSync: %x %x %x ds %x\n",
|
||||
((volatile u_short *)SII_BUF_ADDR)[0],
|
||||
((volatile u_short *)SII_BUF_ADDR)[2],
|
||||
((volatile u_short *)SII_BUF_ADDR)[4],
|
||||
((volatile u_short *)SII_BUF_ADDR(sc))[0],
|
||||
((volatile u_short *)SII_BUF_ADDR(sc))[2],
|
||||
((volatile u_short *)SII_BUF_ADDR(sc))[4],
|
||||
regs->dstat); /* XXX */
|
||||
regs->dmaddrl = (u_short)(SII_BUF_ADDR >> 1);
|
||||
regs->dmaddrh = (u_short)(SII_BUF_ADDR >> 17) & 03;
|
||||
regs->dmaddrl = (u_short)(SII_BUF_ADDR(sc) >> 1);
|
||||
regs->dmaddrh = (u_short)(SII_BUF_ADDR(sc) >> 17) & 03;
|
||||
regs->dmlotc = 5;
|
||||
regs->comm = SII_DMA | SII_INXFER | SII_ATN |
|
||||
(regs->cstat & SII_STATE_MSK) | SII_MSG_OUT_PHASE;
|
||||
|
@ -1775,7 +1748,7 @@ sii_DoSync(regs, state)
|
|||
/* clear the DNE, other errors handled later */
|
||||
regs->dstat = SII_DNE;
|
||||
wbflush();
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
|
||||
#if 0
|
||||
SII_WAIT_UNTIL(dstat, regs->dstat, dstat & (SII_CI | SII_DI),
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* $NetBSD: sii_ds.c,v 1.1 1996/10/13 03:02:40 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 The Board of Trustees of The Leland Stanford
|
||||
* Junior University. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies. Stanford University
|
||||
* makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without
|
||||
* express or implied warranty.
|
||||
*
|
||||
* this driver contributed by Jonathan Stone
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/tty.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <pmax/dev/device.h> /* XXX old pmax SCSI drivers */
|
||||
#include <pmax/dev/siireg.h>
|
||||
#include <pmax/dev/siivar.h>
|
||||
|
||||
#include <pmax/pmax/kn01.h> /* kn01 (ds3100) address constants */
|
||||
|
||||
extern struct cfdriver mainbus_cd; /* XXX */
|
||||
|
||||
/*
|
||||
* Autoconfig definition of driver front-end
|
||||
*/
|
||||
int sii_ds_match __P((struct device * parent, void *cfdata, void *aux));
|
||||
void sii_ds_attach __P((struct device *parent, struct device *self, void *aux));
|
||||
|
||||
|
||||
extern struct cfattach sii_ds_ca;
|
||||
struct cfattach sii_ds_ca = {
|
||||
sizeof(struct siisoftc), sii_ds_match, sii_ds_attach
|
||||
};
|
||||
|
||||
|
||||
/* define a safe address in the SCSI buffer for doing status & message DMA */
|
||||
#define SII_BUF_ADDR (MACH_PHYS_TO_UNCACHED(KN01_SYS_SII_B_START) \
|
||||
+ SII_MAX_DMA_XFER_LENGTH * 14)
|
||||
|
||||
/*
|
||||
* Match driver on Decstation (2100, 3100, 5100) based on name and probe.
|
||||
*/
|
||||
int
|
||||
sii_ds_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
void *match;
|
||||
void *aux;
|
||||
{
|
||||
struct confargs *ca = aux;
|
||||
register void * siiaddr;
|
||||
|
||||
if (strcmp(ca->ca_name, "sii") != 0 &&
|
||||
strncmp(ca->ca_name, "PMAZ-AA ", 8) != 0) /*XXX*/
|
||||
return (0);
|
||||
|
||||
/* XXX check for bad address, untested */
|
||||
siiaddr = (void *)ca->ca_addr;
|
||||
if (siiaddr != (void *)MACH_PHYS_TO_UNCACHED(KN01_SYS_SII)) {
|
||||
kprintf("(siimatch: bad addr %x, substituting %x\n",
|
||||
ca->ca_addr, MACH_PHYS_TO_UNCACHED(KN01_SYS_SII));
|
||||
siiaddr = (void *)MACH_PHYS_TO_UNCACHED(KN01_SYS_SII);
|
||||
}
|
||||
if (badaddr(siiaddr, 4))
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
sii_ds_attach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
{
|
||||
register struct confargs *ca = aux;
|
||||
register struct siisoftc *sc = (struct siisoftc *) self;
|
||||
|
||||
sc->sc_regs = (SIIRegs *)MACH_PHYS_TO_UNCACHED(ca->ca_addr);
|
||||
|
||||
/* set up scsi buffer. XXX Why statically allocated? */
|
||||
sc->sc_buf = (void*)(MACH_PHYS_TO_UNCACHED(KN01_SYS_SII_B_START));
|
||||
|
||||
siiattach(sc);
|
||||
|
||||
/* tie pseudo-slot to device */
|
||||
BUS_INTR_ESTABLISH(ca, siiintr, sc);
|
||||
kprintf("\n");
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/* $NetBSD: siivar.h,v 1.1 1996/10/13 03:02:41 jonathan Exp $ */
|
||||
|
||||
#ifndef _SIIVAR_H
|
||||
#define _SIIVAR_H
|
||||
|
||||
typedef struct scsi_state {
|
||||
int statusByte; /* status byte returned during STATUS_PHASE */
|
||||
int dmaDataPhase; /* which data phase to expect */
|
||||
int dmaCurPhase; /* SCSI phase if DMA is in progress */
|
||||
int dmaPrevPhase; /* SCSI phase of DMA suspended by disconnect */
|
||||
u_short *dmaAddr[2]; /* DMA buffer memory address */
|
||||
int dmaBufIndex; /* which of the above is currently in use */
|
||||
int dmalen; /* amount to transfer in this chunk */
|
||||
int cmdlen; /* total remaining amount of cmd to transfer */
|
||||
u_char *cmd; /* current pointer within scsicmd->cmd */
|
||||
int buflen; /* total remaining amount of data to transfer */
|
||||
char *buf; /* current pointer within scsicmd->buf */
|
||||
u_short flags; /* see below */
|
||||
u_short prevComm; /* command reg before disconnect */
|
||||
u_short dmaCtrl; /* DMA control register if disconnect */
|
||||
u_short dmaAddrL; /* DMA address register if disconnect */
|
||||
u_short dmaAddrH; /* DMA address register if disconnect */
|
||||
u_short dmaCnt; /* DMA count if disconnect */
|
||||
u_short dmaByte; /* DMA byte if disconnect on odd boundary */
|
||||
u_short dmaReqAck; /* DMA synchronous xfer offset or 0 if async */
|
||||
} State;
|
||||
|
||||
/* state flags */
|
||||
#define FIRST_DMA 0x01 /* true if no data DMA started yet */
|
||||
#define PARITY_ERR 0x02 /* true if parity error seen */
|
||||
|
||||
#define SII_NCMD 7
|
||||
struct siisoftc {
|
||||
struct device sc_dev; /* us as a device */
|
||||
void *sc_buf; /* DMA buffer (may be special mem) */
|
||||
SIIRegs *sc_regs; /* HW address of SII controller chip */
|
||||
int sc_flags;
|
||||
int sc_target; /* target SCSI ID if connected */
|
||||
ScsiCmd *sc_cmd[SII_NCMD]; /* active command indexed by ID */
|
||||
State sc_st[SII_NCMD]; /* state info for each active command */
|
||||
#ifdef NEW_SCSI
|
||||
struct scsi_link sc_link; /* scsi lint struct */
|
||||
#endif
|
||||
};
|
||||
|
||||
int siiintr __P((void *sc));
|
||||
|
||||
/* Machine-indepedent back-end attach entry point */
|
||||
void siiattach __P((struct siisoftc *sc));
|
||||
|
||||
#endif /* _SIIVAR_H */
|
Loading…
Reference in New Issue