scsi drivers for fastlane and blizzard controllers that use the

Emulex FAS216 chip.  from Daniel Widenfalk <t94dwi@student.tdb.uu.se>
This commit is contained in:
chopps 1995-05-12 12:59:05 +00:00
parent 9877d5d787
commit 21d667c8ab
9 changed files with 3215 additions and 0 deletions

360
sys/arch/amiga/dev/bzsc.c Normal file
View File

@ -0,0 +1,360 @@
/*
* Copyright (c) 1995 Daniel Widenfalk
* Copyright (c) 1994 Christian E. Hopps
* Copyright (c) 1982, 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)dma.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <machine/pmap.h>
#include <amiga/amiga/custom.h>
#include <amiga/amiga/cc.h>
#include <amiga/amiga/device.h>
#include <amiga/amiga/isr.h>
#include <amiga/dev/sfasreg.h>
#include <amiga/dev/sfasvar.h>
#include <amiga/dev/zbusvar.h>
#include <amiga/dev/bzscreg.h>
#include <amiga/dev/bzscvar.h>
int bzscprint __P((void *auxp, char *));
void bzscattach __P((struct device *, struct device *, void *));
int bzscmatch __P((struct device *, struct cfdata *, void *));
struct scsi_adapter bzsc_scsiswitch = {
sfas_scsicmd,
sfas_minphys,
0, /* no lun support */
0, /* no lun support */
};
struct scsi_device bzsc_scsidev = {
NULL, /* use default error handler */
NULL, /* do not have a start functio */
NULL, /* have no async handler */
NULL, /* Use default done routine */
};
struct cfdriver bzsccd = {
NULL, "bzsc", (cfmatch_t)bzscmatch, bzscattach,
DV_DULL, sizeof(struct bzsc_softc), NULL, 0 };
int bzsc_intr __P((struct sfas_softc *dev));
int bzsc_setup_dma __P((struct sfas_softc *sc, void *ptr, int len,
int mode));
int bzsc_build_dma_chain __P((struct sfas_softc *sc,
struct sfas_dma_chain *chain, void *p, int l));
int bzsc_need_bump __P((struct sfas_softc *sc, void *ptr, int len));
void bzsc_led_dummy __P((struct sfas_softc *sc));
/*
* if we are an Advanced Systems & Software FastlaneZ3
*/
int bzscmatch(struct device *pdp, struct cfdata *cdp, void *auxp)
{
struct zbus_args *zap;
if (!is_a1200())
return(0);
zap = auxp;
if (zap->manid == 0x2140 && zap->prodid == 11)
return(1);
return(0);
}
void bzscattach(struct device *pdp, struct device *dp, void *auxp)
{
struct bzsc_softc *sc;
struct zbus_args *zap;
bzsc_regmap_p rp;
u_int *pte, page;
vu_char *fas;
zap = auxp;
fas = (vu_char *)(((char *)zap->va)+0x10000);
sc = (struct bzsc_softc *)dp;
rp = &sc->sc_regmap;
rp->FAS216.sfas_tc_low = &fas[0x00];
rp->FAS216.sfas_tc_mid = &fas[0x02];
rp->FAS216.sfas_fifo = &fas[0x04];
rp->FAS216.sfas_command = &fas[0x06];
rp->FAS216.sfas_dest_id = &fas[0x08];
rp->FAS216.sfas_timeout = &fas[0x0A];
rp->FAS216.sfas_syncper = &fas[0x0C];
rp->FAS216.sfas_syncoff = &fas[0x0E];
rp->FAS216.sfas_config1 = &fas[0x10];
rp->FAS216.sfas_clkconv = &fas[0x12];
rp->FAS216.sfas_test = &fas[0x14];
rp->FAS216.sfas_config2 = &fas[0x16];
rp->FAS216.sfas_config3 = &fas[0x18];
rp->FAS216.sfas_tc_high = &fas[0x1C];
rp->FAS216.sfas_fifo_bot = &fas[0x1E];
rp->cclkaddr = &fas[0x21];
rp->epowaddr = &fas[0x31];
sc->sc_softc.sc_fas = (sfas_regmap_p)rp;
sc->sc_softc.sc_spec = 0;
sc->sc_softc.sc_led = bzsc_led_dummy;
sc->sc_softc.sc_setup_dma = bzsc_setup_dma;
sc->sc_softc.sc_build_dma_chain = bzsc_build_dma_chain;
sc->sc_softc.sc_need_bump = bzsc_need_bump;
sc->sc_softc.sc_clock_freq = 40; /* BlizzardII 1230 runs at 40MHz? */
sc->sc_softc.sc_timeout = 250; /* Set default timeout to 250ms */
sc->sc_softc.sc_config_flags = 0;
sc->sc_softc.sc_host_id = 7;
sc->sc_softc.sc_bump_sz = NBPG;
sc->sc_softc.sc_bump_pa = 0x0;
sfasinitialize((struct sfas_softc *)sc);
sc->sc_softc.sc_link.adapter_softc = sc;
sc->sc_softc.sc_link.adapter_target = sc->sc_softc.sc_host_id;
sc->sc_softc.sc_link.adapter = &bzsc_scsiswitch;
sc->sc_softc.sc_link.device = &bzsc_scsidev;
sc->sc_softc.sc_link.openings = 1;
printf("\n");
sc->sc_softc.sc_isr.isr_intr = bzsc_intr;
sc->sc_softc.sc_isr.isr_arg = &sc->sc_softc;
sc->sc_softc.sc_isr.isr_ipl = 2;
add_isr(&sc->sc_softc.sc_isr);
/* attach all scsi units on us */
config_found(dp, &sc->sc_softc.sc_link, bzscprint);
}
/* print diag if pnp is NULL else just extra */
int bzscprint(void *auxp, char *pnp)
{
if (pnp == NULL)
return(UNCONF);
return(QUIET);
}
int bzsc_intr(struct sfas_softc *dev)
{
bzsc_regmap_p rp;
int quickints;
rp = (bzsc_regmap_p)dev->sc_fas;
if (!(*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING))
return(0);
quickints = 16;
do {
dev->sc_status = *rp->FAS216.sfas_status;
dev->sc_interrupt = *rp->FAS216.sfas_interrupt;
if (dev->sc_interrupt & SFAS_INT_RESELECTED) {
dev->sc_resel[0] = *rp->FAS216.sfas_fifo;
dev->sc_resel[1] = *rp->FAS216.sfas_fifo;
}
sfasintr(dev);
} while((*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING) &&
--quickints);
return(1);
}
/* --------- */
void bzsc_set_dma_adr(struct sfas_softc *sc, void *ptr, int mode)
{
bzsc_regmap_p rp;
unsigned long p;
rp = (bzsc_regmap_p)sc->sc_fas;
p = ((unsigned long)p)>>1;
if (mode == SFAS_DMA_WRITE)
p |= BZSC_DMA_WRITE;
else
p |= BZSC_DMA_WRITE;
*rp->epowaddr = (u_char)(p>>24) & 0xFF;
*rp->cclkaddr = (u_char)(p>>16) & 0xFF;
*rp->cclkaddr = (u_char)(p>> 8) & 0xFF;
*rp->cclkaddr = (u_char)(p ) & 0xFF;
}
/* Set DMA transfer counter */
void bzsc_set_dma_tc(struct sfas_softc *sc, unsigned int len)
{
*sc->sc_fas->sfas_tc_low = len; len >>= 8;
*sc->sc_fas->sfas_tc_mid = len; len >>= 8;
*sc->sc_fas->sfas_tc_high = len;
}
/* Initialize DMA for transfer */
int bzsc_setup_dma(struct sfas_softc *sc, void *ptr, int len, int mode)
{
int retval;
retval = 0;
switch(mode) {
case SFAS_DMA_READ:
case SFAS_DMA_WRITE:
bzsc_set_dma_adr(sc, ptr, mode);
bzsc_set_dma_tc(sc, len);
break;
case SFAS_DMA_CLEAR:
default:
retval = (*sc->sc_fas->sfas_tc_high << 16) |
(*sc->sc_fas->sfas_tc_mid << 8) |
*sc->sc_fas->sfas_tc_low;
bzsc_set_dma_tc(sc, 0);
break;
}
return(retval);
}
/* Check if address and len is ok for DMA transfer */
int bzsc_need_bump(struct sfas_softc *sc, void *ptr, int len)
{
int p;
p = (int)p & 0x03;
if (p) {
p = 4-p;
if (len < 256)
p = len;
}
return(p);
}
/* Interrupt driven routines */
int bzsc_build_dma_chain(struct sfas_softc *sc, struct sfas_dma_chain *chain,
void *p, int l)
{
int n;
if (!l)
return(0);
#define set_link(n, p, l, f)\
do { chain[n].ptr = (p); chain[n].len = (l); chain[n++].flg = (f); } while(0)
n = 0;
if (l < 512)
set_link(n, (vm_offset_t)p, l, SFAS_CHAIN_BUMP);
else if (
#ifdef M68040
(cpu040 && ((vm_offset_t)p >= 0xFFFC0000)) &&
#endif
((vm_offset_t)p >= 0xFF000000)) {
int len;
while(l) {
len = ((l > sc->sc_bump_sz) ? sc->sc_bump_sz : l);
set_link(n, (vm_offset_t)p, len, SFAS_CHAIN_BUMP);
p += len;
l -= len;
}
} else {
char *ptr;
vm_offset_t pa, lastpa;
int len, prelen, postlen, max_t;
ptr = p;
len = l;
pa = kvtop(ptr);
prelen = ((int)ptr & 0x03);
if (prelen) {
prelen = 4-prelen;
set_link(n, (vm_offset_t)ptr, prelen, SFAS_CHAIN_BUMP);
ptr += prelen;
len -= prelen;
}
lastpa = 0;
while(len > 3) {
pa = kvtop(ptr);
max_t = NBPG - (pa & PGOFSET);
if (max_t > len)
max_t = len;
max_t &= ~3;
if (lastpa == pa)
sc->sc_chain[n-1].len += max_t;
else
set_link(n, pa, max_t, SFAS_CHAIN_DMA);
lastpa = pa+max_t;
ptr += max_t;
len -= max_t;
}
if (len)
set_link(n, (vm_offset_t)ptr, len, SFAS_CHAIN_BUMP);
}
return(n);
}
/* Turn on led */
void bzsc_led_dummy(struct sfas_softc *sc)
{
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 1995 Daniel Widenfalk
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Daniel Widenfalk
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* BlizzardII 1230 with FAS216 SCSI interface hardware description. */
#ifndef _BZSCREG_H_
#define _BZSCREG_H_
#ifndef _SFARREG_H_
#include <amiga/dev/sfasreg.h>
#endif
typedef struct bzsc_regmap {
sfas_regmap_t FAS216;
vu_char *cclkaddr;
vu_char *epowaddr;
} bzsc_regmap_t;
typedef bzsc_regmap_t *bzsc_regmap_p;
#define BZSC_DMA_WRITE 0x80000000
#define BZSC_DMA_READ 0x00000000 /* Symmetric reasons */
#endif

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 1995 Daniel Widenfalk
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Daniel Widenfalk
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BZSCVAR_H_
#define _BZSCVAR_H_
#ifndef _SFASVAR_H_
#include <amiga/dev/sfasvar.h>
#endif
#ifndef _BZSCREG_H_
#include <amiga/dev/bzscreg.h>
#endif
struct bzsc_softc {
struct sfas_softc sc_softc;
bzsc_regmap_t sc_regmap;
};
#endif /* _BZSCVAR_H_ */

449
sys/arch/amiga/dev/flsc.c Normal file
View File

@ -0,0 +1,449 @@
/*
* Copyright (c) 1995 Daniel Widenfalk
* Copyright (c) 1994 Christian E. Hopps
* Copyright (c) 1982, 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)dma.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <machine/pmap.h>
#include <amiga/amiga/custom.h>
#include <amiga/amiga/cc.h>
#include <amiga/amiga/device.h>
#include <amiga/amiga/isr.h>
#include <amiga/dev/sfasreg.h>
#include <amiga/dev/sfasvar.h>
#include <amiga/dev/zbusvar.h>
#include <amiga/dev/flscreg.h>
#include <amiga/dev/flscvar.h>
int flscprint __P((void *auxp, char *));
void flscattach __P((struct device *, struct device *, void *));
int flscmatch __P((struct device *, struct cfdata *, void *));
struct scsi_adapter flsc_scsiswitch = {
sfas_scsicmd,
sfas_minphys,
0, /* no lun support */
0, /* no lun support */
};
struct scsi_device flsc_scsidev = {
NULL, /* use default error handler */
NULL, /* do not have a start functio */
NULL, /* have no async handler */
NULL, /* Use default done routine */
};
struct cfdriver flsccd = {
NULL, "flsc", (cfmatch_t)flscmatch, flscattach,
DV_DULL, sizeof(struct flsc_softc), NULL, 0 };
int flsc_intr __P((struct sfas_softc *dev));
int flsc_setup_dma __P((struct sfas_softc *sc, void *ptr, int len,
int mode));
int flsc_build_dma_chain __P((struct sfas_softc *sc,
struct sfas_dma_chain *chain, void *p, int l));
int flsc_need_bump __P((struct sfas_softc *sc, void *ptr, int len));
void flsc_led __P((struct sfas_softc *sc, int mode));
/*
* if we are an Advanced Systems & Software FastlaneZ3
*/
int
flscmatch(pdp, cdp, auxp)
struct device *pdp;
struct cfdata *cdp;
void *auxp;
{
struct zbus_args *zap;
if (!is_a4000() && !is_a3000())
return(0);
zap = auxp;
if (zap->manid == 0x2140 && zap->prodid == 11)
return(1);
return(0);
}
void
flscattach(pdp, dp, auxp)
struct device *pdp;
struct device *dp;
void *auxp;
{
struct flsc_softc *sc;
struct zbus_args *zap;
flsc_regmap_p rp;
vu_char *fas;
zap = auxp;
fas = &((vu_char *)zap->va)[0x1000001];
sc = (struct flsc_softc *)dp;
rp = &sc->sc_regmap;
rp->FAS216.sfas_tc_low = &fas[0x00];
rp->FAS216.sfas_tc_mid = &fas[0x04];
rp->FAS216.sfas_fifo = &fas[0x08];
rp->FAS216.sfas_command = &fas[0x0C];
rp->FAS216.sfas_dest_id = &fas[0x10];
rp->FAS216.sfas_timeout = &fas[0x14];
rp->FAS216.sfas_syncper = &fas[0x18];
rp->FAS216.sfas_syncoff = &fas[0x1C];
rp->FAS216.sfas_config1 = &fas[0x20];
rp->FAS216.sfas_clkconv = &fas[0x24];
rp->FAS216.sfas_test = &fas[0x28];
rp->FAS216.sfas_config2 = &fas[0x2C];
rp->FAS216.sfas_config3 = &fas[0x30];
rp->FAS216.sfas_tc_high = &fas[0x38];
rp->FAS216.sfas_fifo_bot = &fas[0x3C];
rp->hardbits = &fas[0x40];
rp->clear = &fas[0x80];
rp->dmabase = zap->va;
sc->sc_softc.sc_fas = (sfas_regmap_p)rp;
sc->sc_softc.sc_spec = &sc->sc_specific;
sc->sc_softc.sc_led = flsc_led;
sc->sc_softc.sc_setup_dma = flsc_setup_dma;
sc->sc_softc.sc_build_dma_chain = flsc_build_dma_chain;
sc->sc_softc.sc_need_bump = flsc_need_bump;
sc->sc_softc.sc_clock_freq = 40; /* FastlaneZ3 runs at 40MHz */
sc->sc_softc.sc_timeout = 250; /* Set default timeout to 250ms */
sc->sc_softc.sc_config_flags = 0; /* No config flags yet */
sc->sc_softc.sc_host_id = 7; /* Should check the jumpers */
sc->sc_specific.portbits = 0xA0 | FLSC_PB_EDI | FLSC_PB_ESI;
sc->sc_specific.hardbits = *rp->hardbits;
sc->sc_softc.sc_bump_sz = NBPG;
sc->sc_softc.sc_bump_pa = 0x0;
sfasinitialize((struct sfas_softc *)sc);
sc->sc_softc.sc_link.adapter_softc = sc;
sc->sc_softc.sc_link.adapter_target = sc->sc_softc.sc_host_id;
sc->sc_softc.sc_link.adapter = &flsc_scsiswitch;
sc->sc_softc.sc_link.device = &flsc_scsidev;
sc->sc_softc.sc_link.openings = 1;
sc->sc_softc.sc_isr.isr_intr = flsc_intr;
sc->sc_softc.sc_isr.isr_arg = &sc->sc_softc;
sc->sc_softc.sc_isr.isr_ipl = 2;
add_isr(&sc->sc_softc.sc_isr);
/* We don't want interrupt until we're initialized! */
*rp->hardbits = sc->sc_specific.portbits;
printf("\n");
/* attach all scsi units on us */
config_found(dp, &sc->sc_softc.sc_link, flscprint);
}
/* print diag if pnp is NULL else just extra */
int
flscprint(auxp, pnp)
void *auxp;
char *pnp;
{
if (pnp == NULL)
return(UNCONF);
return(QUIET);
}
int
flsc_intr(dev)
struct sfas_softc *dev;
{
flsc_regmap_p rp;
struct flsc_specific *flspec;
int quickints;
u_char hb;
flspec = dev->sc_spec;
rp = (flsc_regmap_p)dev->sc_fas;
hb = *rp->hardbits;
if (hb & FLSC_HB_IACT)
return(0);
flspec->hardbits = hb;
if ((hb & FLSC_HB_CREQ) &&
!(hb & FLSC_HB_MINT) &&
(*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING)) {
quickints = 16;
do {
dev->sc_status = *rp->FAS216.sfas_status;
dev->sc_interrupt = *rp->FAS216.sfas_interrupt;
if (dev->sc_interrupt & SFAS_INT_RESELECTED) {
dev->sc_resel[0] = *rp->FAS216.sfas_fifo;
dev->sc_resel[1] = *rp->FAS216.sfas_fifo;
}
sfasintr(dev);
} while((*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING)
&& --quickints);
}
/* Reset fastlane interrupt bits */
*rp->hardbits = flspec->portbits & ~FLSC_PB_INT_BITS;
*rp->hardbits = flspec->portbits;
return(1);
}
/* Load transfer adress into dma register */
void
flsc_set_dma_adr(sc, ptr)
struct sfas_softc *sc;
void *ptr;
{
flsc_regmap_p rp;
unsigned int *p;
unsigned int d;
rp = (flsc_regmap_p)sc->sc_fas;
d = (unsigned int)ptr;
p = (unsigned int *)((d & 0xFFFFFF) + (int)rp->dmabase);
*rp->clear=0;
*p = d;
}
/* Set DMA transfer counter */
void
flsc_set_dma_tc(sc, len)
struct sfas_softc *sc;
unsigned int len;
{
*sc->sc_fas->sfas_tc_low = len; len >>= 8;
*sc->sc_fas->sfas_tc_mid = len; len >>= 8;
*sc->sc_fas->sfas_tc_high = len;
}
/* Set DMA mode */
void
flsc_set_dma_mode(sc, mode)
struct sfas_softc *sc;
int mode;
{
struct flsc_specific *spec;
spec = sc->sc_spec;
spec->portbits = (spec->portbits & ~FLSC_PB_DMA_BITS) | mode;
*((flsc_regmap_p)sc->sc_fas)->hardbits = spec->portbits;
}
/* Initialize DMA for transfer */
int
flsc_setup_dma(sc, ptr, len, mode)
struct sfas_softc *sc;
void *ptr;
int len;
int mode;
{
int retval;
retval = 0;
switch(mode) {
case SFAS_DMA_READ:
case SFAS_DMA_WRITE:
flsc_set_dma_adr(sc, ptr);
if (mode == SFAS_DMA_READ)
flsc_set_dma_mode(sc,FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_READ);
else
flsc_set_dma_mode(sc,FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_WRITE);
flsc_set_dma_tc(sc, len);
break;
case SFAS_DMA_CLEAR:
default:
flsc_set_dma_mode(sc, FLSC_PB_DISABLE_DMA);
flsc_set_dma_adr(sc, 0);
retval = (*sc->sc_fas->sfas_tc_high << 16) |
(*sc->sc_fas->sfas_tc_mid << 8) |
*sc->sc_fas->sfas_tc_low;
flsc_set_dma_tc(sc, 0);
break;
}
return(retval);
}
/* Check if address and len is ok for DMA transfer */
int
flsc_need_bump(sc, ptr, len)
struct sfas_softc *sc;
void *ptr;
int len;
{
int p;
p = (int)ptr & 0x03;
if (p) {
p = 4-p;
if (len < 256)
p = len;
}
return(p);
}
/* Interrupt driven routines */
int
flsc_build_dma_chain(sc, chain, p, l)
struct sfas_softc *sc;
struct sfas_dma_chain *chain;
void *p;
int l;
{
vm_offset_t pa, lastpa;
char *ptr;
int len, prelen, postlen, max_t, n;
if (l == 0)
return(0);
#define set_link(n, p, l, f)\
do { chain[n].ptr = (p); chain[n].len = (l); chain[n++].flg = (f); } while(0)
n = 0;
if (l < 512)
set_link(n, (vm_offset_t)p, l, SFAS_CHAIN_BUMP);
else if ((p >= (void *)0xFF000000)
#if M68040
&& (cpu040 && (p >= (void *)0xFFFC0000))
#endif
) {
while(l != 0) {
len = ((l > sc->sc_bump_sz) ? sc->sc_bump_sz : l);
set_link(n, (vm_offset_t)p, len, SFAS_CHAIN_BUMP);
p += len;
l -= len;
}
} else {
ptr = p;
len = l;
pa = kvtop(ptr);
prelen = ((int)ptr & 0x03);
if (prelen) {
prelen = 4-prelen;
set_link(n, (vm_offset_t)ptr, prelen, SFAS_CHAIN_BUMP);
ptr += prelen;
len -= prelen;
}
lastpa = 0;
while(len > 3) {
pa = kvtop(ptr);
max_t = NBPG - (pa & PGOFSET);
if (max_t > len)
max_t = len;
max_t &= ~3;
if (lastpa == pa)
sc->sc_chain[n-1].len += max_t;
else
set_link(n, pa, max_t, SFAS_CHAIN_DMA);
lastpa = pa+max_t;
ptr += max_t;
len -= max_t;
}
if (len)
set_link(n, (vm_offset_t)ptr, len, SFAS_CHAIN_BUMP);
}
return(n);
}
/* Turn on/off led */
void
flsc_led(sc, mode)
struct sfas_softc *sc;
int mode;
{
struct flsc_specific *spec;
flsc_regmap_p rp;
spec = sc->sc_spec;
rp = (flsc_regmap_p)sc->sc_fas;
if (mode) {
sc->sc_led_status++;
spec->portbits |= FLSC_PB_LED;
*rp->hardbits = spec->portbits;
} else {
if (sc->sc_led_status)
sc->sc_led_status--;
if (!sc->sc_led_status) {
spec->portbits &= ~FLSC_PB_LED;
*rp->hardbits = spec->portbits;
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 1995 Daniel Widenfalk
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Daniel Widenfalk
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* FastlaneZ3 with FAS216 SCSI interface hardware description.
*/
#ifndef _FLSCREG_H_
#define _FLSCREG_H_
typedef struct flsc_regmap {
sfas_regmap_t FAS216;
vu_char *hardbits;
vu_char *clear;
vu_char *dmabase;
} flsc_regmap_t;
typedef flsc_regmap_t *flsc_regmap_p;
#define FLSC_HB_DISABLED 0x01
#define FLSC_HB_BUSID6 0x02
#define FLSC_HB_SEAGATE 0x04
#define FLSC_HB_SLOW 0x08
#define FLSC_HB_SYNCHRON 0x10
#define FLSC_HB_CREQ 0x20
#define FLSC_HB_IACT 0x40
#define FLSC_HB_MINT 0x80
#define FLSC_PB_ESI 0x01
#define FLSC_PB_EDI 0x02
#define FLSC_PB_ENABLE_DMA 0x04
#define FLSC_PB_DISABLE_DMA 0x00 /* Symmetric reasons */
#define FLSC_PB_DMA_WRITE 0x08
#define FLSC_PB_DMA_READ 0x00 /* Symmetric reasons */
#define FLSC_PB_LED 0x10
#define FLSC_PB_INT_BITS (FLSC_PB_ESI | FLSC_PB_EDI)
#define FLSC_PB_DMA_BITS (FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_WRITE)
#endif

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 1995 Daniel Widenfalk
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Daniel Widenfalk
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FLSCVAR_H_
#define _FLSCVAR_H_
#ifndef _SFASVAR_H_
#include <amiga/dev/sfasvar.h>
#endif
#ifndef _FLSCREG_H_
#include <amiga/dev/flscvar.h>
#endif
struct flsc_specific {
u_char hardbits;
u_char portbits;
};
struct flsc_softc {
struct sfas_softc sc_softc;
flsc_regmap_t sc_regmap;
struct flsc_specific sc_specific;
};
#endif /* _FLSCVAR_H_ */

1742
sys/arch/amiga/dev/sfas.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,156 @@
/*
* Copyright (c) 1995 Daniel Widenfalk
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Daniel Widenfalk
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SFASREG_H_
#define _SFASREG_H_
/*
* Emulex FAS216 SCSI interface hardware description.
*/
typedef volatile unsigned char vu_char;
typedef struct {
vu_char *sfas_tc_low; /* rw: Transfer count low */
vu_char *sfas_tc_mid; /* rw: Transfer count mid */
vu_char *sfas_fifo; /* rw: Data FIFO */
vu_char *sfas_command; /* rw: Chip command reg */
vu_char *sfas_dest_id; /* w: (Re)select bus ID */
#define sfas_status sfas_dest_id /* r: Status */
vu_char *sfas_timeout; /* w: (Re)select timeout */
#define sfas_interrupt sfas_timeout /* r: Interrupt */
vu_char *sfas_syncper; /* w: Synch. transfer period */
#define sfas_seqstep sfas_syncper /* r: Sequence step */
vu_char *sfas_syncoff; /* w: Synch. transfer offset */
#define sfas_fifo_flags sfas_syncoff /* r: FIFO flags */
vu_char *sfas_config1; /* rw: Config register #1 */
vu_char *sfas_clkconv; /* w: Clock conv. factor */
vu_char *sfas_test; /* w: Test register */
vu_char *sfas_config2; /* rw: Config register #2 */
vu_char *sfas_config3; /* rw: Config register #3 */
vu_char *sfas_tc_high; /* rw: Transfer count high */
vu_char *sfas_fifo_bot; /* w: FIFO bottom register */
} sfas_regmap_t;
typedef sfas_regmap_t *sfas_regmap_p;
/* Commands for the FAS216 */
#define SFAS_CMD_DMA 0x80
#define SFAS_CMD_SEL_NO_ATN 0x41
#define SFAS_CMD_SEL_ATN 0x42
#define SFAS_CMD_SEL_ATN3 0x46
#define SFAS_CMD_SEL_ATN_STOP 0x43
#define SFAS_CMD_ENABLE_RESEL 0x44
#define SFAS_CMD_DISABLE_RESEL 0x45
#define SFAS_CMD_TRANSFER_INFO 0x10
#define SFAS_CMD_TRANSFER_PAD 0x98
#define SFAS_CMD_COMMAND_COMPLETE 0x11
#define SFAS_CMD_MESSAGE_ACCEPTED 0x12
#define SFAS_CMD_SET_ATN 0x1A
#define SFAS_CMD_RESET_ATN 0x1B
#define SFAS_CMD_NOP 0x00
#define SFAS_CMD_FLUSH_FIFO 0x01
#define SFAS_CMD_RESET_CHIP 0x02
#define SFAS_CMD_RESET_SCSI_BUS 0x03
#define SFAS_STAT_PHASE_MASK 0x07
#define SFAS_STAT_PHASE_TRANS_CPLT 0x08
#define SFAS_STAT_TRANSFER_COUNT_ZERO 0x10
#define SFAS_STAT_PARITY_ERROR 0x20
#define SFAS_STAT_GROSS_ERROR 0x40
#define SFAS_STAT_INTERRUPT_PENDING 0x80
#define SFAS_PHASE_DATA_OUT 0
#define SFAS_PHASE_DATA_IN 1
#define SFAS_PHASE_COMMAND 2
#define SFAS_PHASE_STATUS 3
#define SFAS_PHASE_MESSAGE_OUT 6
#define SFAS_PHASE_MESSAGE_IN 7
#define SFAS_DEST_ID_MASK 0x07
#define SFAS_INT_SELECTED 0x01
#define SFAS_INT_SELECTED_WITH_ATN 0x02
#define SFAS_INT_RESELECTED 0x04
#define SFAS_INT_FUNCTION_COMPLETE 0x08
#define SFAS_INT_BUS_SERVICE 0x10
#define SFAS_INT_DISCONNECT 0x20
#define SFAS_INT_ILLEGAL_COMMAND 0x40
#define SFAS_INT_SCSI_RESET_DETECTED 0x80
#define SFAS_SYNCHRON_PERIOD_MASK 0x1F
#define SFAS_FIFO_COUNT_MASK 0x1F
#define SFAS_FIFO_SEQUENCE_STEP_MASK 0xE0
#define SFAS_FIFO_SEQUENCE_SHIFT 5
#define SFAS_SYNCHRON_OFFSET_MASK 0x0F
#define SFAS_SYNC_ASSERT_MASK 0x30
#define SFAS_SYNC_ASSERT_SHIFT 4
#define SFAS_SYNC_DEASSERT_MASK 0x30
#define SFAS_SYNC_DEASSERT_SHIFT 6
#define SFAS_CFG1_BUS_ID_MASK 0x07
#define SFAS_CFG1_CHIP_TEST_MODE 0x08
#define SFAS_CFG1_SCSI_PARITY_ENABLE 0x10
#define SFAS_CFG1_PARITY_TEST_MODE 0x20
#define SFAS_CFG1_SCSI_RES_INT_DIS 0x40
#define SFAS_CFG1_SLOW_CABLE_MODE 0x80
#define SFAS_CLOCK_CONVERSION_MASK 0x07
#define SFAS_TEST_TARGET_TEST_MODE 0x01
#define SFAS_TEST_INITIATOR_TEST_MODE 0x02
#define SFAS_TEST_TRISTATE_TEST_MODE 0x04
#define SFAS_CFG2_DMA_PARITY_ENABLE 0x01
#define SFAS_CFG2_REG_PARITY_ENABLE 0x02
#define SFAS_CFG2_TARG_BAD_PARITY_ABORT 0x04
#define SFAS_CFG2_SCSI_2_MODE 0x08
#define SFAS_CFG2_TRISTATE_DMA_REQ 0x10
#define SFAS_CFG2_BYTE_CONTROL_MODE 0x20
#define SFAS_CFG2_FEATURES_ENABLE 0x40
#define SFAS_CFG2_RESERVE_FIFO_BYTE 0x80
#define SFAS_CFG3_THRESHOLD_8_MODE 0x01
#define SFAS_CFG3_ALTERNATE_DMA_MODE 0x02
#define SFAS_CFG3_SAVE_RESIDUAL_BYTE 0x04
#define SFAS_CFG3_FASTCLK 0x08
#define SFAS_CFG3_FASTSCSI 0x10
#define SFAS_CFG3_CDB10 0x20
#define SFAS_CFG3_QENB 0x40
#define SFAS_CFG3_IDRESCHK 0x80
#endif

View File

@ -0,0 +1,295 @@
/*
* Copyright (c) 1995 Daniel Widenfalk
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Daniel Widenfalk
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SFASVAR_H_
#define _SFASVAR_H_
#ifndef _SFASREG_H_
#include <amiga/dev/sfasreg.h>
#endif
/*
* Do not define if we don't need the vm FIX
*/
#define SFAS_NEED_VM_PATCH 1
/*
* MAXCHAIN is the anticipated maximum number of chain blocks needed. This
* assumes that we are NEVER requested to transfer more than MAXPHYS bytes.
*/
#define MAXCHAIN (MAXPHYS/NBPG+2)
/*
* Maximum number of requests standing by. Could be anything, but I think 9
* looks nice :-) NOTE: This does NOT include requests already started!
*/
#define MAXPENDING 9 /* 7 IDs + 2 extra */
/*
* DMA chain block. If flg == SFAS_CHAIN_PRG or flg == SFAS_CHAIN_BUMP then
* ptr is a VIRTUAL adress. If flg == SFAS_CHAIN_DMA then ptr is a PHYSICAL
* adress.
*/
struct sfas_dma_chain {
vm_offset_t ptr;
u_short len;
short flg;
};
#define SFAS_CHAIN_DMA 0x00
#define SFAS_CHAIN_BUMP 0x01
#define SFAS_CHAIN_PRG 0x02
/*
* This is the data that we need for the vm FIX. offset is the offset into
* the first page. pa is the physical adress of each page. pages is the number
* of slots used in pa. If pages == 0 the we don't need the FIX right now.
*/
#ifdef SFAS_NEED_VM_PATCH
struct vm_link_data {
vm_offset_t pa[MAXCHAIN];
short offset;
short pages;
};
#endif
/*
* This struct contains the necessary info for a pending request. Pointer to
* a scsi_xfer struct and an optional vm_link_data.
*/
struct sfas_pending {
TAILQ_ENTRY(sfas_pending) link;
struct scsi_xfer *xs;
#ifdef SFAS_NEED_VM_PATCH
struct vm_link_data vm_link_data;
#endif
};
/*
* nexus contains all active data for one SCSI unit. Parts of the info in this
* struct survives between scsi commands.
*/
struct nexus {
struct scsi_xfer *xs; /* Pointer to request */
u_char ID; /* ID message to be sent */
u_char clen; /* scsi command length + */
u_char cbuf[14]; /* the actual command bytes */
struct sfas_dma_chain dma[MAXCHAIN]; /* DMA chain blocks */
short max_link; /* Maximum used of above */
short cur_link; /* Currently handled block */
u_char *buf; /* Virtual adress of data */
int len; /* Bytes left to transfer */
vm_offset_t dma_buf; /* Current DMA adress */
int dma_len; /* Current DMA length */
vm_offset_t dma_blk_ptr; /* Current chain adress */
int dma_blk_len; /* Current chain length */
u_char dma_blk_flg; /* Current chain flags */
u_char state; /* Nexus state, see below */
u_short flags; /* Nexus flags, see below */
short period; /* Sync period to request */
u_char offset; /* Sync offset to request */
u_char syncper; /* FAS216 variable storage */
u_char syncoff; /* FAS216 variable storage */
u_char config3; /* FAS216 variable storage */
u_char lun_unit; /* (Lun<<4) | Unit of nexus */
u_char status; /* Status byte from unit*/
#ifdef SFAS_NEED_VM_PATCH
struct vm_link_data vm_link_data; /* Optional vm FIX data */
#endif
};
/* SCSI nexus_states */
#define SFAS_NS_IDLE 0 /* Nexus idle */
#define SFAS_NS_SELECTED 1 /* Last command was a SELECT command */
#define SFAS_NS_DATA_IN 2 /* Last command was a TRANSFER_INFO */
/* command during a data in phase */
#define SFAS_NS_DATA_OUT 3 /* Last command was a TRANSFER_INFO */
/* command during a data out phase */
#define SFAS_NS_STATUS 4 /* We have send a COMMAND_COMPLETE */
/* command and are awaiting status */
#define SFAS_NS_MSG_IN 5 /* Last phase was MESSAGE IN */
#define SFAS_NS_MSG_OUT 6 /* Last phase was MESSAGE OUT */
#define SFAS_NS_SVC 7 /* We have sent the command */
#define SFAS_NS_DISCONNECTING 8 /* We have recieved a disconnect msg */
#define SFAS_NS_DISCONNECTED 9 /* We are disconnected */
#define SFAS_NS_RESELECTED 10 /* We was reselected */
#define SFAS_NS_DONE 11 /* Done. Prephsase to FINISHED */
#define SFAS_NS_FINISHED 12 /* Realy done. Call scsi_done */
#define SFAS_NS_SENSE 13 /* We are requesting sense */
#define SFAS_NS_RESET 14 /* We are reseting this unit */
/* SCSI nexus flags */
#define SFAS_NF_UNIT_BUSY 0x0001 /* Unit is not available */
#define SFAS_NF_SELECT_ME 0x0002 /* Nexus is set up, waiting for bus */
#define SFAS_NF_REQUEST_SENSE 0x0004 /* We should request sense */
#define SFAS_NF_SENSING 0x0008 /* We are sensing */
#define SFAS_NF_HAS_MSG 0x0010 /* We have recieved a complete msg */
#define SFAS_NF_DO_SDTR 0x0020 /* We should send a SDTR */
#define SFAS_NF_SDTR_SENT 0x0040 /* We have sent a SDTR */
#define SFAS_NF_SYNC_TESTED 0x0080 /* We have negotiated sync */
#define SFAS_NF_RESET 0x0100 /* Reset this nexus */
#define SFAS_NF_IMMEDIATE 0x0200 /* We are operating from sfasicmd */
#define SFAS_NF_DEBUG 0x8000 /* As it says: DEBUG */
struct sfas_softc {
struct device sc_dev; /* System required struct */
struct scsi_link sc_link; /* For sub devices */
struct isr sc_isr; /* Interrupt chain struct */
TAILQ_HEAD(,sfas_pending) sc_xs_pending;
TAILQ_HEAD(,sfas_pending) sc_xs_free;
struct sfas_pending sc_xs_store[MAXPENDING];
sfas_regmap_p sc_fas; /* FAS216 Address */
void *sc_spec; /* Board-specific data */
#ifdef SFAS_NEED_VM_PATCH
u_char *sc_vm_link;
#endif
u_char *sc_bump_va; /* Bumpbuf virtual adr */
vm_offset_t sc_bump_pa; /* Bumpbuf physical adr */
int sc_bump_sz; /* Bumpbuf size */
/* Configuration registers, must be set BEFORE sfasinitialize */
u_char sc_clock_freq;
u_short sc_timeout;
u_char sc_host_id;
u_char sc_config_flags;
/* Generic DMA functions */
int (*sc_setup_dma)();
int (*sc_build_dma_chain)();
int (*sc_need_bump)();
/* Generic Led data */
int sc_led_status;
void (*sc_led)();
/* Nexus list */
struct nexus sc_nexus[8];
struct nexus *sc_cur_nexus;
struct nexus *sc_sel_nexus;
/* Current transfer data */
#ifdef SFAS_NEED_VM_PATCH
short sc_vm_link_pages;
#endif
u_char *sc_buf; /* va */
int sc_len;
vm_offset_t sc_dma_buf; /* pa */
int sc_dma_len;
vm_offset_t sc_dma_blk_ptr;
int sc_dma_blk_len;
short sc_dma_blk_flg;
struct sfas_dma_chain *sc_chain; /* Current DMA chain */
short sc_max_link;
short sc_cur_link;
/* Interrupt registers */
u_char sc_status;
u_char sc_interrupt;
u_char sc_resel[2];
u_char sc_units_disconnected;
/* Storage for FAS216 config registers (current values) */
u_char sc_config1;
u_char sc_config2;
u_char sc_config3;
u_char sc_clock_conv_fact;
u_char sc_timeout_val;
u_char sc_clock_period;
u_char sc_msg_in[7];
u_char sc_msg_in_len;
u_char sc_msg_out[7];
u_char sc_msg_out_len;
u_char sc_unit;
u_char sc_lun;
u_char sc_flags;
};
#define SFAS_DMA_READ 0
#define SFAS_DMA_WRITE 1
#define SFAS_DMA_CLEAR 2
/* sc_flags */
#define SFAS_ACTIVE 0x01
#define SFAS_DONT_WAIT 0x02
#ifdef SFAS_NEED_VM_PATCH
#define SFAS_HAS_VM_LINK 0x04
#endif
/* SCSI Selection modes */
#define SFAS_SELECT 0x00 /* Normal selection: No sync, no resel */
#define SFAS_SELECT_R 0x01 /* Reselection allowed */
#define SFAS_SELECT_S 0x02 /* Synchronous transfer allowed */
#define SFAS_SELECT_I 0x04 /* Selection for sfasicmd */
#define SFAS_SELECT_K 0x08 /* Send a BUS DEVICE RESET message (Kill) */
/* Nice abbreviations of the above */
#define SFAS_SELECT_RS (SFAS_SELECT_R|SFAS_SELECT_S)
#define SFAS_SELECT_RI (SFAS_SELECT_R|SFAS_SELECT_I)
#define SFAS_SELECT_SI (SFAS_SELECT_S|SFAS_SELECT_I)
#define SFAS_SELECT_RSI (SFAS_SELECT_R|SFAS_SELECT_S|SFAS_SELECT_I)
/* sc_config_flags */
#define SFAS_NO_SYNCH 0x01 /* Disable synchronous transfer */
#define SFAS_NO_DMA 0x02 /* Do not use DMA! EVER! */
#define SFAS_NO_RESELECT 0x04 /* Do not allow relesection */
#define SFAS_SLOW_CABLE 0x08 /* Cable is "unsafe" for fast scsi-2 */
#define SFAS_SLOW_START 0x10 /* There are slow starters on the bus */
void sfasinitialize __P((struct sfas_softc *sc));
void sfas_minphys __P((struct buf *bp));
int sfas_scsicmd __P((struct scsi_xfer *));
#endif /* _SFASVAR_H_ */