Split si & sw attach routines, and make the si part use the new VME interface.

This commit is contained in:
pk 1998-01-25 16:37:08 +00:00
parent f8ba1e0bd9
commit 4efb52487a

View File

@ -1,4 +1,4 @@
/* $NetBSD: si.c,v 1.41 1998/01/12 20:23:56 thorpej Exp $ */
/* $NetBSD: si.c,v 1.42 1998/01/25 16:37:08 pk Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -104,6 +104,7 @@
#include <vm/vm.h>
#include <machine/bus.h>
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/pmap.h>
@ -111,6 +112,8 @@
#include <sparc/sparc/vaddrs.h>
#include <sparc/sparc/cpuvar.h>
#include <dev/vme/vmevar.h>
#include <dev/scsipi/scsi_all.h>
#include <dev/scsipi/scsipi_all.h>
#include <dev/scsipi/scsipi_debug.h>
@ -204,9 +207,14 @@ int sw_options = SI_ENABLE_DMA;
int si_dma_intr_timo = 500; /* ticks (sec. X 100) */
static int si_match __P((struct device *, struct cfdata *, void *));
static int sw_match __P((struct device *, struct cfdata *, void *));
static void si_attach __P((struct device *, struct device *, void *));
static void sw_attach __P((struct device *, struct device *, void *));
static void si_attach_common __P((struct device *, struct si_softc *));
static int si_intr __P((void *));
static void si_reset_adapter __P((struct ncr5380_softc *));
static void sw_reset_adapter __P((struct ncr5380_softc *));
static void (*reset_adapter) __P((struct ncr5380_softc *));
static void si_minphys __P((struct buf *));
void si_dma_alloc __P((struct ncr5380_softc *));
@ -253,9 +261,34 @@ struct cfattach si_ca = {
/* The Sun "SCSI Weird" 4/100 obio controller. */
struct cfattach sw_ca = {
sizeof(struct si_softc), si_match, si_attach
sizeof(struct si_softc), sw_match, sw_attach
};
static int
sw_match(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
/* Nothing but a Sun 4/100 is going to have these devices. */
if (cpuinfo.cpu_type != CPUTYP_4_100)
return (0);
/*
* Default interrupt priority always is 3. At least, that's
* what my board seems to be at. --thorpej
*/
if (ra->ra_intr[0].int_pri == -1)
ra->ra_intr[0].int_pri = 3;
/* Make sure there is something there... */
return (probeget(ra->ra_vaddr + 1, 1) != -1);
}
static int
si_match(parent, cf, aux)
struct device *parent;
@ -265,12 +298,8 @@ si_match(parent, cf, aux)
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
/* Are we looking for the right thing? */
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
return (0);
/* Nothing but a Sun 4 is going to have these devices. */
if (!CPU_ISSUN4)
if (!CPU_ISSUN4 || cpuinfo.cpu_type == CPUTYP_4_100)
return (0);
/*
@ -280,27 +309,6 @@ si_match(parent, cf, aux)
if (ra->ra_intr[0].int_pri == -1)
ra->ra_intr[0].int_pri = 3;
/* Figure out the bus type and look for the appropriate adapter. */
switch (ca->ca_bustype) {
case BUS_VME16:
/* AFAIK, the `si' can only exist on the vmes. */
if (strcmp(ra->ra_name, "si") ||
cpuinfo.cpu_type == CPUTYP_4_100)
return (0);
break;
case BUS_OBIO:
/* AFAIK, an `sw' can only exist on the obio. */
if (strcmp(ra->ra_name, "sw") ||
cpuinfo.cpu_type != CPUTYP_4_100)
return (0);
break;
default:
/* Don't know what we ended up with ... */
return (0);
}
/* Make sure there is something there... */
if (probeget(ra->ra_vaddr + 1, 1) == -1)
return (0);
@ -311,24 +319,113 @@ si_match(parent, cf, aux)
* be determined using the fact that the "sc" board occupies
* 4K bytes in VME space but the "si" board occupies 2K bytes.
*/
if (strcmp(cf->cf_driver->cd_name, "si") == 0)
if (probeget(ra->ra_vaddr + 0x801, 1) != -1)
return(0);
return (1);
return (probeget(ra->ra_vaddr + 0x801, 1) == -1);
}
static void
si_attach(parent, self, args)
si_attach(parent, self, aux)
struct device *parent, *self;
void *args;
void *aux;
{
struct si_softc *sc = (struct si_softc *) self;
struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *)sc;
struct vme_attach_args *va = aux;
vme_chipset_tag_t ct = va->vma_chipset_tag;
bus_space_tag_t bt = va->vma_bustag;
bus_space_handle_t bh;
vme_intr_handle_t ih;
vme_mod_t mod;
mod = VMEMOD_A24 | VMEMOD_D | VMEMOD_S;
if (vme_bus_map(ct, va->vma_reg[0], sizeof(struct si_regs),
mod, bt, &bh) != 0)
panic("%s: vme_bus_map", ncr_sc->sc_dev.dv_xname);
sc->sc_regs = (struct si_regs *)bh;
sc->sc_options = si_options;
reset_adapter = si_reset_adapter;
ncr_sc->sc_dma_setup = si_vme_dma_setup;
ncr_sc->sc_dma_start = si_vme_dma_start;
ncr_sc->sc_dma_eop = si_vme_dma_stop;
ncr_sc->sc_dma_stop = si_vme_dma_stop;
vme_intr_map(ct, va->vma_vec, va->vma_pri, &ih);
vme_intr_establish(ct, ih, si_intr, sc);
printf(" pri %d\n", va->vma_pri);
sc->sc_adapter_iv_am = (mod << 8) | (va->vma_vec & 0xFF);
si_attach_common(parent, sc);
if (sc->sc_options & SI_DO_RESELECT) {
/*
* Need to enable interrupts (and DMA!)
* on this H/W for reselect to work.
*/
ncr_sc->sc_intr_on = si_vme_intr_on;
ncr_sc->sc_intr_off = si_vme_intr_off;
}
bootpath_store(1, NULL);
}
static void
sw_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
struct si_softc *sc = (struct si_softc *) self;
struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *)sc;
volatile struct si_regs *regs;
struct confargs *ca = args;
struct romaux *ra = &ca->ca_ra;
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
struct bootpath *bp;
/* Map the controller registers. */
sc->sc_regs = (struct si_regs *)
mapiodev(ra->ra_reg, 0, sizeof(struct si_regs));
sc->sc_options = sw_options;
sc->sc_adapter_type = ca->ca_bustype;
reset_adapter = sw_reset_adapter;
ncr_sc->sc_dma_setup = si_obio_dma_setup;
ncr_sc->sc_dma_start = si_obio_dma_start;
ncr_sc->sc_dma_eop = si_obio_dma_stop;
ncr_sc->sc_dma_stop = si_obio_dma_stop;
ncr_sc->sc_intr_on = si_obio_intr_on;
ncr_sc->sc_intr_off = si_obio_intr_off;
/* Establish the interrupt. */
sc->sc_ih.ih_fun = si_intr;
sc->sc_ih.ih_arg = sc;
intr_establish(ra->ra_intr[0].int_pri, &sc->sc_ih);
printf(" pri %d\n", ra->ra_intr[0].int_pri);
/*
* If the boot path is "sw" or "si" at the moment and it's me, then
* walk out pointer to the sub-device, ready for the config
* below.
*/
bp = ra->ra_bp;
if (bp != NULL && strcmp(bp->name, ra->ra_name) == 0 &&
bp->val[0] == -1 && bp->val[1] == ncr_sc->sc_dev.dv_unit)
bootpath_store(1, bp + 1);
si_attach_common(parent, sc);
bootpath_store(1, NULL);
}
static void
si_attach_common(parent, sc)
struct device *parent;
struct si_softc *sc;
{
struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *)sc;
volatile struct si_regs *regs;
char bits[64];
int i;
@ -339,13 +436,8 @@ si_attach(parent, self, args)
if ((ncr_sc->sc_dev.dv_cfdata->cf_flags & SI_OPTIONS_MASK) != 0)
sc->sc_options =
(ncr_sc->sc_dev.dv_cfdata->cf_flags & SI_OPTIONS_MASK);
else
sc->sc_options =
(ca->ca_bustype == BUS_OBIO) ? sw_options : si_options;
/* Map the controller registers. */
regs = (struct si_regs *)
mapiodev(ra->ra_reg, 0, sizeof(struct si_regs));
regs = sc->sc_regs;
/*
* Fill in the prototype scsipi_link.
@ -377,36 +469,6 @@ si_attach(parent, self, args)
ncr_sc->sc_dma_free = si_dma_free;
ncr_sc->sc_dma_poll = si_dma_poll;
switch (ca->ca_bustype) {
case BUS_VME16:
ncr_sc->sc_dma_setup = si_vme_dma_setup;
ncr_sc->sc_dma_start = si_vme_dma_start;
ncr_sc->sc_dma_eop = si_vme_dma_stop;
ncr_sc->sc_dma_stop = si_vme_dma_stop;
if (sc->sc_options & SI_DO_RESELECT) {
/*
* Need to enable interrupts (and DMA!)
* on this H/W for reselect to work.
*/
ncr_sc->sc_intr_on = si_vme_intr_on;
ncr_sc->sc_intr_off = si_vme_intr_off;
}
break;
case BUS_OBIO:
ncr_sc->sc_dma_setup = si_obio_dma_setup;
ncr_sc->sc_dma_start = si_obio_dma_start;
ncr_sc->sc_dma_eop = si_obio_dma_stop;
ncr_sc->sc_dma_stop = si_obio_dma_stop;
ncr_sc->sc_intr_on = si_obio_intr_on;
ncr_sc->sc_intr_off = si_obio_intr_off;
break;
default:
panic("\nsi_attach: impossible bus type 0x%x", ca->ca_bustype);
/* NOTREACHED */
}
ncr_sc->sc_flags = 0;
if ((sc->sc_options & SI_DO_RESELECT) == 0)
ncr_sc->sc_no_disconnect = 0xFF;
@ -414,12 +476,6 @@ si_attach(parent, self, args)
ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
/*
* Initialize fields used only here in the MD code.
*/
sc->sc_regs = regs;
sc->sc_adapter_type = ca->ca_bustype;
/* sc_adapter_iv_am = (was set above) */
/*
* Allocate DMA handles.
@ -431,36 +487,7 @@ si_attach(parent, self, args)
for (i = 0; i < SCI_OPENINGS; i++)
sc->sc_dma[i].dh_flags = 0;
sc->sc_regs = regs;
sc->sc_adapter_type = ca->ca_bustype;
/* Establish the interrupt. */
sc->sc_ih.ih_fun = si_intr;
sc->sc_ih.ih_arg = sc;
switch (ca->ca_bustype) {
case BUS_OBIO:
/*
* This will be an "sw" controller.
*/
intr_establish(ra->ra_intr[0].int_pri, &sc->sc_ih);
break;
case BUS_VME16:
/*
* This will be an "si" controller.
*/
vmeintr_establish(ra->ra_intr[0].int_vec,
ra->ra_intr[0].int_pri, &sc->sc_ih);
sc->sc_adapter_iv_am =
VME_SUPV_DATA_24 | (ra->ra_intr[0].int_vec & 0xFF);
break;
default:
/* Impossible case handled above. */
break;
}
printf(" pri %d\n", ra->ra_intr[0].int_pri);
if (sc->sc_options) {
printf("%s: options=%s\n", ncr_sc->sc_dev.dv_xname,
bitmask_snprintf(sc->sc_options, SI_OPTIONS_BITS,
@ -475,24 +502,12 @@ si_attach(parent, self, args)
/*
* Initialize si board itself.
*/
si_reset_adapter(ncr_sc);
reset_adapter(ncr_sc);
ncr5380_init(ncr_sc);
ncr5380_reset_scsibus(ncr_sc);
/*
* If the boot path is "sw" or "si" at the moment and it's me, then
* walk out pointer to the sub-device, ready for the config
* below.
*/
bp = ra->ra_bp;
if (bp != NULL && strcmp(bp->name, ra->ra_name) == 0 &&
bp->val[0] == -1 && bp->val[1] == ncr_sc->sc_dev.dv_unit)
bootpath_store(1, bp + 1);
/* Configure sub-devices */
config_found(self, &(ncr_sc->sc_link), scsiprint);
bootpath_store(1, NULL);
config_found(&ncr_sc->sc_dev, &ncr_sc->sc_link, scsiprint);
}
static void
@ -580,31 +595,43 @@ si_reset_adapter(struct ncr5380_softc *ncr_sc)
*
* The reset bits in the CSR are active low.
*/
switch(sc->sc_adapter_type) {
case BUS_VME16:
si->si_csr = 0;
delay(10);
si->si_csr = SI_CSR_FIFO_RES | SI_CSR_SCSI_RES | SI_CSR_INTR_EN;
delay(10);
si->fifo_count = 0;
si->dma_addrh = 0;
si->dma_addrl = 0;
si->dma_counth = 0;
si->dma_countl = 0;
si->si_iv_am = sc->sc_adapter_iv_am;
si->fifo_cnt_hi = 0;
break;
si->si_csr = 0;
delay(10);
si->si_csr = SI_CSR_FIFO_RES | SI_CSR_SCSI_RES | SI_CSR_INTR_EN;
delay(10);
si->fifo_count = 0;
si->dma_addrh = 0;
si->dma_addrl = 0;
si->dma_counth = 0;
si->dma_countl = 0;
si->si_iv_am = sc->sc_adapter_iv_am;
si->fifo_cnt_hi = 0;
case BUS_OBIO:
si->sw_csr = 0;
delay(10);
si->sw_csr = SI_CSR_SCSI_RES;
si->dma_addr = 0;
si->dma_count = 0;
delay(10);
si->sw_csr |= SI_CSR_INTR_EN;
break;
SCI_CLR_INTR(ncr_sc);
}
static void
sw_reset_adapter(struct ncr5380_softc *ncr_sc)
{
struct si_softc *sc = (struct si_softc *)ncr_sc;
volatile struct si_regs *si = sc->sc_regs;
#ifdef DEBUG
if (si_debug) {
printf("sw_reset_adapter\n");
}
#endif
/*
* The reset bits in the CSR are active low.
*/
si->sw_csr = 0;
delay(10);
si->sw_csr = SI_CSR_SCSI_RES;
si->dma_addr = 0;
si->dma_count = 0;
delay(10);
si->sw_csr |= SI_CSR_INTR_EN;
SCI_CLR_INTR(ncr_sc);
}