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:
jonathan 1996-10-13 03:02:39 +00:00
parent de83b4558f
commit 986daa1436
3 changed files with 200 additions and 80 deletions

View File

@ -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),

View File

@ -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");
}

View File

@ -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 */