From 986daa1436fd95f92026778e75c43bc5aba320dd Mon Sep 17 00:00:00 2001 From: jonathan Date: Sun, 13 Oct 1996 03:02:39 +0000 Subject: [PATCH] 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 --- sys/arch/pmax/dev/sii.c | 133 +++++++++++++++---------------------- sys/arch/pmax/dev/sii_ds.c | 96 ++++++++++++++++++++++++++ sys/arch/pmax/dev/siivar.h | 51 ++++++++++++++ 3 files changed, 200 insertions(+), 80 deletions(-) create mode 100644 sys/arch/pmax/dev/sii_ds.c create mode 100644 sys/arch/pmax/dev/siivar.h diff --git a/sys/arch/pmax/dev/sii.c b/sys/arch/pmax/dev/sii.c index 250844bb52d1..f8a0c0c7a5f0 100644 --- a/sys/arch/pmax/dev/sii.c +++ b/sys/arch/pmax/dev/sii.c @@ -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 #include #include +#include -#include -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), diff --git a/sys/arch/pmax/dev/sii_ds.c b/sys/arch/pmax/dev/sii_ds.c new file mode 100644 index 000000000000..26d4b7015265 --- /dev/null +++ b/sys/arch/pmax/dev/sii_ds.c @@ -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 +#include +#include +#include +#include +#include +#include /* XXX old pmax SCSI drivers */ +#include +#include + +#include /* 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"); +} diff --git a/sys/arch/pmax/dev/siivar.h b/sys/arch/pmax/dev/siivar.h new file mode 100644 index 000000000000..b36103ef4ce3 --- /dev/null +++ b/sys/arch/pmax/dev/siivar.h @@ -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 */