* Rewrite asc driver with ``mi'' backend and parent-specific front-end
cfattach code for TC SCSI option cards and ioasic 53c94 baseboard SCSI. ascvar.h: shared softc declarations asc_ioasic.c: ioasic front-end code. asc_tc.c: Turbochannel option (and 5000/200 basebard) front-end code. * ioasic_attach meeds more work to eliminate pmax_type dependency and to verify the clocks speed passed to 53c94. * Add prototypes for asc script entry points; should compile with -Wstrict-prototypes -Wmissing-prototypes. * Use tcvar.h interface. The usage of tc_syncbus() and tc_mb() may not be quite stylistically on an Alhpa, but it apparently makes no difference on the eerly-generation Alpha CPUs in TC Alphas.
This commit is contained in:
parent
3f15a06497
commit
8eca2b2bb4
407
sys/dev/tc/asc.c
407
sys/dev/tc/asc.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: asc.c,v 1.27 1996/08/28 19:01:36 cgd Exp $ */
|
||||
/* $NetBSD: asc.c,v 1.28 1996/09/25 21:07:46 jonathan Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -148,12 +148,10 @@
|
||||
|
||||
#include <pmax/pmax/asic.h>
|
||||
#include <pmax/pmax/kmin.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
|
||||
|
||||
/*#define readback(a) { register int foo; wbflush(); foo = (a); }*/
|
||||
#define readback(a) { register int foo; foo = (a); }
|
||||
extern int pmax_boardtype;
|
||||
|
||||
/*
|
||||
* In 4ns ticks.
|
||||
@ -194,10 +192,8 @@ int asc_to_scsi_period[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Internal forward declarations.
|
||||
* Debugging log of SCSI operations.
|
||||
*/
|
||||
static void asc_reset();
|
||||
static void asc_startcmd();
|
||||
|
||||
#ifdef DEBUG
|
||||
int asc_debug = 1;
|
||||
@ -217,6 +213,14 @@ struct asc_log {
|
||||
void asc_DumpLog __P((char *str));
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Script, scsi state, and device softc structure declarations.
|
||||
* script pointers occur in both scsi state and the softc,
|
||||
* so they are defined first.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Scripts are entries in a state machine table.
|
||||
* A script has four parts: a pre-condition, an action, a command to the chip,
|
||||
@ -230,32 +234,49 @@ void asc_DumpLog __P((char *str));
|
||||
* script proceeds if the action routine returns TRUE.
|
||||
* See asc_intr() for how and where this is all done.
|
||||
*/
|
||||
struct asc_softc;
|
||||
typedef struct script {
|
||||
int condition; /* expected state at interrupt time */
|
||||
int (*action)(); /* extra operations */
|
||||
|
||||
int (*action) /* extra operations */
|
||||
__P((register struct asc_softc *asc, register int status,
|
||||
register int ss, register int ir));
|
||||
int command; /* command to the chip */
|
||||
struct script *next; /* index into asc_scripts for next state */
|
||||
} script_t;
|
||||
|
||||
|
||||
/*
|
||||
* script definitions
|
||||
*/
|
||||
|
||||
/* Matching on the condition value */
|
||||
#define SCRIPT_MATCH(ir, csr) ((ir) | (((csr) & 0x67) << 8))
|
||||
|
||||
/*
|
||||
* A typedef for a script function, to use in forward declarations.
|
||||
*/
|
||||
typedef int
|
||||
script_fn_t __P((register struct asc_softc *asc, register int status,
|
||||
register int ss, register int ir));
|
||||
|
||||
|
||||
/* forward decls of script actions */
|
||||
static int script_nop(); /* when nothing needed */
|
||||
static int asc_end(); /* all come to an end */
|
||||
static int asc_get_status(); /* get status from target */
|
||||
static int asc_dma_in(); /* start reading data from target */
|
||||
static int asc_last_dma_in(); /* cleanup after all data is read */
|
||||
static int asc_resume_in(); /* resume data in after a message */
|
||||
static int asc_resume_dma_in(); /* resume DMA after a disconnect */
|
||||
static int asc_dma_out(); /* send data to target via dma */
|
||||
static int asc_last_dma_out(); /* cleanup after all data is written */
|
||||
static int asc_resume_out(); /* resume data out after a message */
|
||||
static int asc_resume_dma_out(); /* resume DMA after a disconnect */
|
||||
static int asc_sendsync(); /* negotiate sync xfer */
|
||||
static int asc_replysync(); /* negotiate sync xfer */
|
||||
static int asc_msg_in(); /* process a message byte */
|
||||
static int asc_disconnect(); /* process an expected disconnect */
|
||||
static script_fn_t script_nop; /* when nothing needed */
|
||||
static script_fn_t asc_end; /* all come to an end */
|
||||
static script_fn_t asc_get_status; /* get status from target */
|
||||
static script_fn_t asc_dma_in; /* start reading data from target */
|
||||
static script_fn_t asc_last_dma_in; /* cleanup after all data is read */
|
||||
static script_fn_t asc_resume_in; /* resume data in after a message */
|
||||
static script_fn_t asc_resume_dma_in; /* resume DMA after a disconnect */
|
||||
static script_fn_t asc_dma_out; /* send data to target via dma */
|
||||
static script_fn_t asc_last_dma_out; /* cleanup after all data is written */
|
||||
static script_fn_t asc_resume_out; /* resume data out after a message */
|
||||
static script_fn_t asc_resume_dma_out; /* resume DMA after a disconnect */
|
||||
static script_fn_t asc_sendsync; /* negotiate sync xfer */
|
||||
static script_fn_t asc_replysync; /* negotiate sync xfer */
|
||||
static script_fn_t asc_msg_in; /* process a message byte */
|
||||
static script_fn_t asc_disconnect; /* process an expected disconnect */
|
||||
|
||||
/* Define the index into asc_scripts for various state transitions */
|
||||
#define SCRIPT_DATA_IN 0
|
||||
@ -379,92 +400,14 @@ script_t asc_scripts[] = {
|
||||
&asc_scripts[SCRIPT_GET_STATUS]},
|
||||
};
|
||||
|
||||
/*
|
||||
* State kept for each active SCSI device.
|
||||
*/
|
||||
typedef struct scsi_state {
|
||||
script_t *script; /* saved script while processing error */
|
||||
int statusByte; /* status byte returned during STATUS_PHASE */
|
||||
int error; /* errno to pass back to device driver */
|
||||
u_char *dmaBufAddr; /* DMA buffer address */
|
||||
u_int dmaBufSize; /* DMA buffer size */
|
||||
int dmalen; /* amount to transfer in this chunk */
|
||||
int dmaresid; /* amount not transfered if chunk suspended */
|
||||
int buflen; /* total remaining amount of data to transfer */
|
||||
char *buf; /* current pointer within scsicmd->buf */
|
||||
int flags; /* see below */
|
||||
int msglen; /* number of message bytes to read */
|
||||
int msgcnt; /* number of message bytes received */
|
||||
u_char sync_period; /* DMA synchronous period */
|
||||
u_char sync_offset; /* DMA synchronous xfer offset or 0 if async */
|
||||
u_char msg_out; /* next MSG_OUT byte to send */
|
||||
u_char msg_in[16]; /* buffer for multibyte messages */
|
||||
} State;
|
||||
|
||||
/* state flags */
|
||||
#define DISCONN 0x001 /* true if currently disconnected from bus */
|
||||
#define DMA_IN_PROGRESS 0x002 /* true if data DMA started */
|
||||
#define DMA_IN 0x004 /* true if reading from SCSI device */
|
||||
#define DMA_OUT 0x010 /* true if writing to SCSI device */
|
||||
#define DID_SYNC 0x020 /* true if synchronous offset was negotiated */
|
||||
#define TRY_SYNC 0x040 /* true if try neg. synchronous offset */
|
||||
#define PARITY_ERR 0x080 /* true if parity error seen */
|
||||
#define CHECK_SENSE 0x100 /* true if doing sense command */
|
||||
#include <dev/tc/ascvar.h>
|
||||
|
||||
/*
|
||||
* State kept for each active SCSI host interface (53C94).
|
||||
* Internal forward declarations.
|
||||
*/
|
||||
struct asc_softc {
|
||||
struct device sc_dev; /* us as a device */
|
||||
asc_regmap_t *regs; /* chip address */
|
||||
volatile int *dmar; /* DMA address register address */
|
||||
u_char *buff; /* RAM buffer address (uncached) */
|
||||
int sc_id; /* SCSI ID of this interface */
|
||||
int myidmask; /* ~(1 << myid) */
|
||||
int state; /* current SCSI connection state */
|
||||
int target; /* target SCSI ID if busy */
|
||||
script_t *script; /* next expected interrupt & action */
|
||||
ScsiCmd *cmd[ASC_NCMD]; /* active command indexed by SCSI ID */
|
||||
State st[ASC_NCMD]; /* state info for each active command */
|
||||
void (*dma_start)(); /* Start dma routine */
|
||||
void (*dma_end)(); /* End dma routine */
|
||||
u_char *dma_next;
|
||||
int dma_xfer; /* Dma len still to go */
|
||||
int min_period; /* Min transfer period clk/byte */
|
||||
int max_period; /* Max transfer period clk/byte */
|
||||
int ccf; /* CCF, whatever that really is? */
|
||||
int timeout_250; /* 250ms timeout */
|
||||
int tb_ticks; /* 4ns. ticks/tb channel ticks */
|
||||
#ifdef USE_NEW_SCSI
|
||||
struct scsi_link sc_link; /* scsi link struct */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ASC_STATE_IDLE 0 /* idle state */
|
||||
#define ASC_STATE_BUSY 1 /* selecting or currently connected */
|
||||
#define ASC_STATE_TARGET 2 /* currently selected as target */
|
||||
#define ASC_STATE_RESEL 3 /* currently waiting for reselect */
|
||||
|
||||
typedef struct asc_softc *asc_softc_t;
|
||||
|
||||
/*
|
||||
* Dma operations.
|
||||
*/
|
||||
#define ASCDMA_READ 1
|
||||
#define ASCDMA_WRITE 2
|
||||
static void tb_dma_start(), tb_dma_end(), asic_dma_start(), asic_dma_end();
|
||||
extern u_long asc_iomem;
|
||||
|
||||
|
||||
/*
|
||||
* Autoconfiguration data for config.
|
||||
*/
|
||||
int ascmatch __P((struct device * parent, void *cfdata, void *aux));
|
||||
void ascattach __P((struct device *parent, struct device *self, void *aux));
|
||||
|
||||
struct cfattach asc_ca = {
|
||||
sizeof(struct asc_softc), ascmatch, ascattach
|
||||
};
|
||||
static void asc_reset __P((asc_softc_t asc, asc_regmap_t *regs));
|
||||
static void asc_startcmd __P((asc_softc_t asc, int target));
|
||||
|
||||
extern struct cfdriver asc_cd;
|
||||
struct cfdriver asc_cd = {
|
||||
@ -492,112 +435,51 @@ struct scsi_device asc_dev = {
|
||||
/*
|
||||
* Definition of the controller for the old auto-configuration program.
|
||||
*/
|
||||
void asc_start();
|
||||
void asc_start __P((register ScsiCmd *scsicmd));
|
||||
int asc_intr __P ((void *asc));
|
||||
struct pmax_driver ascdriver = {
|
||||
"asc", NULL, asc_start, 0, asc_intr,
|
||||
};
|
||||
|
||||
void asc_minphys __P((struct buf *bp));
|
||||
|
||||
extern struct cfdriver ioasic_cd; /* XXX */
|
||||
|
||||
/*
|
||||
* Match driver based on name
|
||||
* bus-parent shared attach function
|
||||
*/
|
||||
int
|
||||
ascmatch(parent, match, aux)
|
||||
struct device *parent;
|
||||
void *match;
|
||||
void *aux;
|
||||
{
|
||||
struct ioasicdev_attach_args *d = aux;
|
||||
struct tc_attach_args *t = aux;
|
||||
void *ascaddr;
|
||||
|
||||
/*if (parent->dv_cfdata->cf_driver == &ioasic_cd) */
|
||||
if (strncmp(d->iada_modname, "asc", TC_ROM_LLEN) &&
|
||||
strncmp(d->iada_modname, "PMAZ-AA ", TC_ROM_LLEN))
|
||||
return (0);
|
||||
|
||||
if (parent->dv_cfdata->cf_driver == &ioasic_cd)
|
||||
ascaddr = (void*)d->iada_addr;
|
||||
else
|
||||
ascaddr = (void*)t->ta_addr;
|
||||
|
||||
if (badaddr(ascaddr + ASC_OFFSET_53C94, 4))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ascattach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
ascattach(asc, dmabufsize, bus_speed)
|
||||
register asc_softc_t asc;
|
||||
int dmabufsize;
|
||||
{
|
||||
register struct ioasicdev_attach_args *d = aux;
|
||||
register struct tc_attach_args *t = aux;
|
||||
register asc_softc_t asc = (asc_softc_t) self;
|
||||
register asc_regmap_t *regs;
|
||||
int id, s, i;
|
||||
int bufsiz;
|
||||
|
||||
void *ascaddr;
|
||||
int unit;
|
||||
|
||||
if (asc->sc_dev.dv_parent->dv_cfdata->cf_driver == &ioasic_cd) {
|
||||
ascaddr = (void*)MACH_PHYS_TO_UNCACHED(d->iada_addr);
|
||||
} else {
|
||||
ascaddr = (void*)MACH_PHYS_TO_UNCACHED(t->ta_addr);
|
||||
}
|
||||
unit = asc->sc_dev.dv_unit;
|
||||
|
||||
/*
|
||||
* Initialize hw descriptor, cache some pointers
|
||||
*/
|
||||
asc->regs = (asc_regmap_t *)(ascaddr + ASC_OFFSET_53C94);
|
||||
|
||||
/*
|
||||
* Set up machine dependencies.
|
||||
* (1) how to do dma
|
||||
* (2) timing based on turbochannel frequency
|
||||
* (1) timing based on turbochannel frequency
|
||||
*/
|
||||
|
||||
if (asc->sc_dev.dv_parent->dv_cfdata->cf_driver == &ioasic_cd) {
|
||||
asc->buff = (u_char *)MACH_PHYS_TO_UNCACHED(asc_iomem);
|
||||
bufsiz = 8192;
|
||||
*((volatile int *)IOASIC_REG_SCSI_DMAPTR(ioasic_base)) = -1;
|
||||
*((volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base)) = -1;
|
||||
*((volatile int *)IOASIC_REG_SCSI_SCR(ioasic_base)) = 0;
|
||||
asc->dma_start = asic_dma_start;
|
||||
asc->dma_end = asic_dma_end;
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* Fall through for turbochannel option.
|
||||
*/
|
||||
asc->dmar = (volatile int *)(ascaddr + ASC_OFFSET_DMAR);
|
||||
asc->buff = (u_char *)(ascaddr + ASC_OFFSET_RAM);
|
||||
bufsiz = PER_TGT_DMA_SIZE;
|
||||
asc->dma_start = tb_dma_start;
|
||||
asc->dma_end = tb_dma_end;
|
||||
};
|
||||
/* dma setup done in parent-specific attach code */
|
||||
|
||||
/*
|
||||
* Now for timing. The 3max has a 25Mhz tb whereas the 3min and
|
||||
* maxine are 12.5Mhz.
|
||||
*/
|
||||
switch (pmax_boardtype) {
|
||||
case DS_3MAX:
|
||||
case DS_3MAXPLUS:
|
||||
switch (bus_speed) {
|
||||
case ASC_SPEED_25_MHZ:
|
||||
asc->min_period = ASC_MIN_PERIOD25;
|
||||
asc->max_period = ASC_MAX_PERIOD25;
|
||||
asc->ccf = ASC_CCF(25);
|
||||
asc->timeout_250 = ASC_TIMEOUT_250(25, asc->ccf);
|
||||
asc->tb_ticks = 10;
|
||||
break;
|
||||
case DS_3MIN:
|
||||
case DS_MAXINE:
|
||||
|
||||
case ASC_SPEED_12_5_MHZ:
|
||||
default:
|
||||
asc->min_period = ASC_MIN_PERIOD12;
|
||||
asc->max_period = ASC_MAX_PERIOD12;
|
||||
@ -649,21 +531,13 @@ ascattach(parent, self, aux)
|
||||
* We may want to try ping ponging buffers later.
|
||||
*/
|
||||
for (i = 0; i < ASC_NCMD; i++) {
|
||||
asc->st[i].dmaBufAddr = asc->buff + bufsiz * i;
|
||||
asc->st[i].dmaBufSize = bufsiz;
|
||||
asc->st[i].dmaBufAddr = asc->buff + dmabufsize * i;
|
||||
asc->st[i].dmaBufSize = dmabufsize;
|
||||
}
|
||||
|
||||
/* Hack for old-sytle SCSI-device probe */
|
||||
(void) pmax_add_scsi(&ascdriver, unit);
|
||||
|
||||
/* tie pseudo-slot to device */
|
||||
if (asc->sc_dev.dv_parent->dv_cfdata->cf_driver == &ioasic_cd)
|
||||
ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_BIO,
|
||||
asc_intr, asc);
|
||||
else
|
||||
tc_intr_establish(parent, t->ta_cookie, TC_IPL_BIO,
|
||||
asc_intr, asc);
|
||||
|
||||
printf(": target %d\n", id);
|
||||
|
||||
|
||||
@ -765,17 +639,17 @@ asc_reset(asc, regs)
|
||||
* Reset chip and wait till done
|
||||
*/
|
||||
regs->asc_cmd = ASC_CMD_RESET;
|
||||
wbflush(); DELAY(25);
|
||||
tc_syncbus(); DELAY(25);
|
||||
|
||||
/* spec says this is needed after reset */
|
||||
regs->asc_cmd = ASC_CMD_NOP;
|
||||
wbflush(); DELAY(25);
|
||||
tc_syncbus(); DELAY(25);
|
||||
|
||||
/*
|
||||
* Set up various chip parameters
|
||||
*/
|
||||
regs->asc_ccf = asc->ccf;
|
||||
wbflush(); DELAY(25);
|
||||
tc_syncbus(); DELAY(25);
|
||||
regs->asc_sel_timo = asc->timeout_250;
|
||||
/* restore our ID */
|
||||
regs->asc_cnfg1 = asc->sc_id | ASC_CNFG1_P_CHECK;
|
||||
@ -786,7 +660,7 @@ asc_reset(asc, regs)
|
||||
ASC_TC_PUT(regs, 0);
|
||||
regs->asc_syn_p = asc->min_period;
|
||||
regs->asc_syn_o = 0; /* async for now */
|
||||
wbflush();
|
||||
tc_mb();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -895,7 +769,7 @@ asc_startcmd(asc, target)
|
||||
|
||||
/* preload the FIFO with the message to be sent */
|
||||
regs->asc_fifo = SCSI_DIS_REC_IDENTIFY;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
|
||||
/* initialize the DMA */
|
||||
(*asc->dma_start)(asc, state, state->dmaBufAddr, ASCDMA_WRITE);
|
||||
@ -1051,7 +925,7 @@ again:
|
||||
ASC_TC_GET(regs, len);
|
||||
fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
|
||||
printf("asc_intr: ignoring strange interrupt");
|
||||
printf(" tc %d fifo residue\n", len, fifo);
|
||||
printf(" tc %d fifo residue %d\n", len, fifo);
|
||||
goto done;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@ -1113,7 +987,7 @@ again:
|
||||
printf("asc_intr: dmalen %d len %d fifo %d\n",
|
||||
state->dmalen, len, fifo); /* XXX */
|
||||
regs->asc_cmd = ASC_CMD_FLUSH;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
readback(regs->asc_cmd);
|
||||
DELAY(2);
|
||||
}
|
||||
@ -1342,7 +1216,7 @@ again:
|
||||
*/
|
||||
|
||||
done:
|
||||
wbflush();
|
||||
tc_mb();
|
||||
/* watch out for HW race conditions and setup & hold time violations */
|
||||
ir = regs->asc_status;
|
||||
while (ir != (status = regs->asc_status))
|
||||
@ -1874,13 +1748,13 @@ asc_sendsync(asc, status, ss, ir)
|
||||
|
||||
/* send the extended synchronous negotiation message */
|
||||
regs->asc_fifo = SCSI_EXTENDED_MSG;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
regs->asc_fifo = 3;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
regs->asc_fifo = SCSI_MIN_PERIOD;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
regs->asc_fifo = ASC_MAX_OFFSET;
|
||||
/* state to resume after we see the sync reply message */
|
||||
state->script = asc->script + 2;
|
||||
@ -1905,13 +1779,13 @@ asc_replysync(asc, status, ss, ir)
|
||||
#endif
|
||||
/* send synchronous transfer in response to a request */
|
||||
regs->asc_fifo = SCSI_EXTENDED_MSG;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
regs->asc_fifo = 3;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
regs->asc_fifo = asc_to_scsi_period[state->sync_period] * asc->tb_ticks;
|
||||
wbflush();
|
||||
tc_mb();
|
||||
regs->asc_fifo = state->sync_offset;
|
||||
regs->asc_cmd = ASC_CMD_XFER_INFO;
|
||||
readback(regs->asc_cmd);
|
||||
@ -2136,131 +2010,6 @@ asc_disconnect(asc, status, ss, ir)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* DMA handling routines. For a turbochannel device, just set the dmar.
|
||||
* For the I/O ASIC, handle the actual DMA interface.
|
||||
*/
|
||||
static void
|
||||
tb_dma_start(asc, state, cp, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
caddr_t cp;
|
||||
int flag;
|
||||
{
|
||||
|
||||
if (flag == ASCDMA_WRITE)
|
||||
*asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(cp);
|
||||
else
|
||||
*asc->dmar = ASC_DMA_ADDR(cp);
|
||||
}
|
||||
|
||||
static void
|
||||
tb_dma_end(asc, state, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
int flag;
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
asic_dma_start(asc, state, cp, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
caddr_t cp;
|
||||
int flag;
|
||||
{
|
||||
register volatile u_int *ssr = (volatile u_int *)
|
||||
IOASIC_REG_CSR(ioasic_base);
|
||||
u_int phys, nphys;
|
||||
|
||||
/* stop DMA engine first */
|
||||
*ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
*((volatile int *)IOASIC_REG_SCSI_SCR(ioasic_base)) = 0;
|
||||
|
||||
phys = MACH_CACHED_TO_PHYS(cp);
|
||||
cp = (caddr_t)mips_trunc_page(cp + NBPG);
|
||||
nphys = MACH_CACHED_TO_PHYS(cp);
|
||||
|
||||
asc->dma_next = cp;
|
||||
asc->dma_xfer = state->dmalen - (nphys - phys);
|
||||
|
||||
*(volatile int *)IOASIC_REG_SCSI_DMAPTR(ioasic_base) =
|
||||
IOASIC_DMA_ADDR(phys);
|
||||
*(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
|
||||
IOASIC_DMA_ADDR(nphys);
|
||||
if (flag == ASCDMA_READ)
|
||||
*ssr |= IOASIC_CSR_SCSI_DIR | IOASIC_CSR_DMAEN_SCSI;
|
||||
else
|
||||
*ssr = (*ssr & ~IOASIC_CSR_SCSI_DIR) | IOASIC_CSR_DMAEN_SCSI;
|
||||
wbflush();
|
||||
}
|
||||
|
||||
static void
|
||||
asic_dma_end(asc, state, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
int flag;
|
||||
{
|
||||
register volatile u_int *ssr = (volatile u_int *)
|
||||
IOASIC_REG_CSR(ioasic_base);
|
||||
register volatile u_int *dmap = (volatile u_int *)
|
||||
IOASIC_REG_SCSI_DMAPTR(ioasic_base);
|
||||
register u_short *to;
|
||||
register int w;
|
||||
int nb;
|
||||
|
||||
*ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
to = (u_short *)MACH_PHYS_TO_CACHED(*dmap >> 3);
|
||||
*dmap = -1;
|
||||
*((volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base)) = -1;
|
||||
wbflush();
|
||||
|
||||
if (flag == ASCDMA_READ) {
|
||||
MachFlushDCache(MACH_PHYS_TO_CACHED(
|
||||
MACH_UNCACHED_TO_PHYS(state->dmaBufAddr)), state->dmalen);
|
||||
if ( (nb = *((int *)IOASIC_REG_SCSI_SCR(ioasic_base))) != 0) {
|
||||
/* pick up last upto6 bytes, sigh. */
|
||||
|
||||
/* Last byte really xferred is.. */
|
||||
w = *(int *)IOASIC_REG_SCSI_SDR0(ioasic_base);
|
||||
*to++ = w;
|
||||
if (--nb > 0) {
|
||||
w >>= 16;
|
||||
*to++ = w;
|
||||
}
|
||||
if (--nb > 0) {
|
||||
w = *(int *)IOASIC_REG_SCSI_SDR1(ioasic_base);
|
||||
*to++ = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* Called by asic_intr() for scsi dma pointer update interrupts.
|
||||
*/
|
||||
void
|
||||
asc_dma_intr()
|
||||
{
|
||||
asc_softc_t asc = &asc_cd.cd_devs[0]; /*XXX*/
|
||||
u_int next_phys;
|
||||
|
||||
asc->dma_xfer -= NBPG;
|
||||
if (asc->dma_xfer <= -NBPG) {
|
||||
volatile u_int *ssr = (volatile u_int *)
|
||||
IOASIC_REG_CSR(ioasic_base);
|
||||
*ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
} else {
|
||||
asc->dma_next += NBPG;
|
||||
next_phys = MACH_CACHED_TO_PHYS(asc->dma_next);
|
||||
}
|
||||
*(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
|
||||
IOASIC_DMA_ADDR(next_phys);
|
||||
wbflush();
|
||||
}
|
||||
#endif /*notdef*/
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
|
244
sys/dev/tc/asc_ioasic.c
Normal file
244
sys/dev/tc/asc_ioasic.c
Normal file
@ -0,0 +1,244 @@
|
||||
/* $NetBSD: asc_ioasic.c,v 1.1 1996/09/25 21:07:54 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.
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <dev/tc/tcvar.h>
|
||||
#include <dev/tc/ioasicvar.h>
|
||||
#include <machine/autoconf.h>
|
||||
|
||||
#include <pmax/dev/device.h> /* XXX */
|
||||
#include <pmax/dev/scsi.h> /* XXX */
|
||||
|
||||
#include <pmax/dev/ascreg.h> /* XXX */
|
||||
#include <dev/tc/ascvar.h>
|
||||
|
||||
#include <mips/locore.h> /* XXX XXX bus.h needs cache-consistency*/
|
||||
|
||||
/*XXX*/
|
||||
#include <pmax/pmax/asic.h> /* XXX ioasic register defs? */
|
||||
#include <pmax/pmax/kmin.h> /* XXX ioasic register defs? */
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
extern int pmax_boardtype;
|
||||
|
||||
|
||||
/*
|
||||
* Autoconfiguration data for config.
|
||||
*/
|
||||
int asc_ioasic_match __P((struct device *, void *, void *));
|
||||
void asc_ioasic_attach __P((struct device *, struct device *, void *));
|
||||
|
||||
struct cfattach asc_ioasic_ca = {
|
||||
sizeof(struct asc_softc), asc_ioasic_match, asc_ioasic_attach
|
||||
};
|
||||
|
||||
/*
|
||||
* DMA callback declarations
|
||||
*/
|
||||
|
||||
extern u_long asc_iomem;
|
||||
static void
|
||||
asic_dma_start __P((asc_softc_t asc, State *state, caddr_t cp, int flag));
|
||||
|
||||
static void
|
||||
asic_dma_end __P((asc_softc_t asc, State *state, int flag));
|
||||
|
||||
int
|
||||
asc_ioasic_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
void *match;
|
||||
void *aux;
|
||||
{
|
||||
struct ioasicdev_attach_args *d = aux;
|
||||
void *ascaddr;
|
||||
|
||||
if (strncmp(d->iada_modname, "asc", TC_ROM_LLEN) &&
|
||||
strncmp(d->iada_modname, "PMAZ-AA ", TC_ROM_LLEN))
|
||||
return (0);
|
||||
|
||||
/* probe for chip */
|
||||
ascaddr = (void*)d->iada_addr;
|
||||
if (tc_badaddr(ascaddr + ASC_OFFSET_53C94))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
asc_ioasic_attach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
{
|
||||
register struct ioasicdev_attach_args *d = aux;
|
||||
register asc_softc_t asc = (asc_softc_t) self;
|
||||
int bufsiz, speed;
|
||||
|
||||
void *ascaddr;
|
||||
int unit;
|
||||
|
||||
ascaddr = (void*)MACH_PHYS_TO_UNCACHED(d->iada_addr);
|
||||
unit = asc->sc_dev.dv_unit;
|
||||
|
||||
/*
|
||||
* Initialize hw descriptor, cache some pointers
|
||||
*/
|
||||
asc->regs = (asc_regmap_t *)(ascaddr + ASC_OFFSET_53C94);
|
||||
|
||||
/*
|
||||
* Set up machine dependencies.
|
||||
* (1) how to do dma
|
||||
* (2) timing based on turbochannel frequency
|
||||
*/
|
||||
|
||||
asc->buff = (u_char *)MACH_PHYS_TO_UNCACHED(asc_iomem);
|
||||
bufsiz = 8192;
|
||||
*((volatile int *)IOASIC_REG_SCSI_DMAPTR(ioasic_base)) = -1;
|
||||
*((volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base)) = -1;
|
||||
*((volatile int *)IOASIC_REG_SCSI_SCR(ioasic_base)) = 0;
|
||||
asc->dma_start = asic_dma_start;
|
||||
asc->dma_end = asic_dma_end;
|
||||
|
||||
/*
|
||||
* Now for timing. The 3max has a 25Mhz tb whereas the 3min and
|
||||
* maxine are 12.5Mhz.
|
||||
*/
|
||||
|
||||
/*printf(" (bus speed: %d) ", t->ta_busspeed);*/
|
||||
/* XXX don't these run at 25MHz on any ioasic??*/
|
||||
switch (pmax_boardtype) {
|
||||
case DS_3MAX:
|
||||
case DS_3MAXPLUS:
|
||||
speed = ASC_SPEED_25_MHZ;
|
||||
break;
|
||||
case DS_3MIN:
|
||||
case DS_MAXINE:
|
||||
default:
|
||||
speed = ASC_SPEED_12_5_MHZ;
|
||||
break;
|
||||
};
|
||||
|
||||
ascattach(asc, bufsiz, speed);
|
||||
|
||||
/* tie pseudo-slot to device */
|
||||
|
||||
ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_BIO,
|
||||
asc_intr, asc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DMA handling routines. For a turbochannel device, just set the dmar.
|
||||
* For the I/O ASIC, handle the actual DMA interface.
|
||||
*/
|
||||
static void
|
||||
asic_dma_start(asc, state, cp, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
caddr_t cp;
|
||||
int flag;
|
||||
{
|
||||
register volatile u_int *ssr = (volatile u_int *)
|
||||
IOASIC_REG_CSR(ioasic_base);
|
||||
u_int phys, nphys;
|
||||
|
||||
/* stop DMA engine first */
|
||||
*ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
*((volatile int *)IOASIC_REG_SCSI_SCR(ioasic_base)) = 0;
|
||||
|
||||
phys = MACH_CACHED_TO_PHYS(cp);
|
||||
cp = (caddr_t)mips_trunc_page(cp + NBPG);
|
||||
nphys = MACH_CACHED_TO_PHYS(cp);
|
||||
|
||||
asc->dma_next = cp;
|
||||
asc->dma_xfer = state->dmalen - (nphys - phys);
|
||||
|
||||
*(volatile int *)IOASIC_REG_SCSI_DMAPTR(ioasic_base) =
|
||||
IOASIC_DMA_ADDR(phys);
|
||||
*(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
|
||||
IOASIC_DMA_ADDR(nphys);
|
||||
if (flag == ASCDMA_READ)
|
||||
*ssr |= IOASIC_CSR_SCSI_DIR | IOASIC_CSR_DMAEN_SCSI;
|
||||
else
|
||||
*ssr = (*ssr & ~IOASIC_CSR_SCSI_DIR) | IOASIC_CSR_DMAEN_SCSI;
|
||||
wbflush();
|
||||
}
|
||||
|
||||
static void
|
||||
asic_dma_end(asc, state, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
int flag;
|
||||
{
|
||||
register volatile u_int *ssr = (volatile u_int *)
|
||||
IOASIC_REG_CSR(ioasic_base);
|
||||
register volatile u_int *dmap = (volatile u_int *)
|
||||
IOASIC_REG_SCSI_DMAPTR(ioasic_base);
|
||||
register u_short *to;
|
||||
register int w;
|
||||
int nb;
|
||||
|
||||
*ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
to = (u_short *)MACH_PHYS_TO_CACHED(*dmap >> 3);
|
||||
*dmap = -1;
|
||||
*((volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base)) = -1;
|
||||
wbflush();
|
||||
|
||||
if (flag == ASCDMA_READ) {
|
||||
MachFlushDCache(MACH_PHYS_TO_CACHED(
|
||||
MACH_UNCACHED_TO_PHYS(state->dmaBufAddr)), state->dmalen);
|
||||
if ( (nb = *((int *)IOASIC_REG_SCSI_SCR(ioasic_base))) != 0) {
|
||||
/* pick up last upto6 bytes, sigh. */
|
||||
|
||||
/* Last byte really xferred is.. */
|
||||
w = *(int *)IOASIC_REG_SCSI_SDR0(ioasic_base);
|
||||
*to++ = w;
|
||||
if (--nb > 0) {
|
||||
w >>= 16;
|
||||
*to++ = w;
|
||||
}
|
||||
if (--nb > 0) {
|
||||
w = *(int *)IOASIC_REG_SCSI_SDR1(ioasic_base);
|
||||
*to++ = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* Called by asic_intr() for scsi dma pointer update interrupts.
|
||||
*/
|
||||
void
|
||||
asc_dma_intr()
|
||||
{
|
||||
asc_softc_t asc = &asc_cd.cd_devs[0]; /*XXX*/
|
||||
u_int next_phys;
|
||||
|
||||
asc->dma_xfer -= NBPG;
|
||||
if (asc->dma_xfer <= -NBPG) {
|
||||
volatile u_int *ssr = (volatile u_int *)
|
||||
IOASIC_REG_CSR(ioasic_base);
|
||||
*ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
} else {
|
||||
asc->dma_next += NBPG;
|
||||
next_phys = MACH_CACHED_TO_PHYS(asc->dma_next);
|
||||
}
|
||||
*(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
|
||||
IOASIC_DMA_ADDR(next_phys);
|
||||
wbflush();
|
||||
}
|
||||
#endif /*notdef*/
|
169
sys/dev/tc/asc_tc.c
Normal file
169
sys/dev/tc/asc_tc.c
Normal file
@ -0,0 +1,169 @@
|
||||
/* $NetBSD: asc_tc.c,v 1.1 1996/09/25 21:07:53 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/device.h>
|
||||
#include <dev/tc/tcvar.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <dev/tc/ioasicvar.h>
|
||||
|
||||
#include <pmax/dev/device.h> /* XXX */
|
||||
#include <pmax/dev/scsi.h> /* XXX */
|
||||
|
||||
#include <pmax/dev/ascreg.h> /* XXX */
|
||||
#include <dev/tc/ascvar.h>
|
||||
|
||||
/*XXX*/
|
||||
|
||||
|
||||
/*
|
||||
* Autoconfiguration data for config.
|
||||
*/
|
||||
int asc_tc_match __P((struct device *, void *, void *));
|
||||
void asc_tc_attach __P((struct device *, struct device *, void *));
|
||||
|
||||
struct cfattach asc_tc_ca = {
|
||||
sizeof(struct asc_softc), asc_tc_match, asc_tc_attach
|
||||
};
|
||||
|
||||
/*
|
||||
* DMA callbacks
|
||||
*/
|
||||
|
||||
static void
|
||||
tc_dma_start __P((struct asc_softc *asc, struct scsi_state *state,
|
||||
caddr_t cp, int flag));
|
||||
|
||||
static void
|
||||
tc_dma_end __P((struct asc_softc *asc, struct scsi_state *state,
|
||||
int flag));
|
||||
|
||||
|
||||
int
|
||||
asc_tc_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
void *match;
|
||||
void *aux;
|
||||
{
|
||||
struct tc_attach_args *t = aux;
|
||||
void *ascaddr;
|
||||
|
||||
if (strncmp(t->ta_modname, "PMAZ-AA ", TC_ROM_LLEN))
|
||||
return (0);
|
||||
|
||||
ascaddr = (void*)t->ta_addr;
|
||||
|
||||
if (tc_badaddr(ascaddr + ASC_OFFSET_53C94))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
asc_tc_attach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
{
|
||||
register struct tc_attach_args *t = aux;
|
||||
register asc_softc_t asc = (asc_softc_t) self;
|
||||
int bufsiz, speed;
|
||||
|
||||
void *ascaddr;
|
||||
int unit;
|
||||
|
||||
ascaddr = (void*)MACH_PHYS_TO_UNCACHED(t->ta_addr);
|
||||
unit = asc->sc_dev.dv_unit;
|
||||
|
||||
/*
|
||||
* Initialize hw descriptor, cache some pointers
|
||||
*/
|
||||
asc->regs = (asc_regmap_t *)(ascaddr + ASC_OFFSET_53C94);
|
||||
|
||||
/*
|
||||
* Set up machine dependencies.
|
||||
* (1) how to do dma
|
||||
* (2) timing based on turbochannel frequency
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fall through for turbochannel option.
|
||||
*/
|
||||
asc->dmar = (volatile int *)(ascaddr + ASC_OFFSET_DMAR);
|
||||
asc->buff = (u_char *)(ascaddr + ASC_OFFSET_RAM);
|
||||
bufsiz = PER_TGT_DMA_SIZE;
|
||||
asc->dma_start = tc_dma_start;
|
||||
asc->dma_end = tc_dma_end;
|
||||
|
||||
/*
|
||||
* Now for timing. The 3max has a 25Mhz tb whereas the 3min and
|
||||
* maxine are 12.5Mhz.
|
||||
*/
|
||||
printf(" (bus speed: %d) ", t->ta_busspeed);
|
||||
|
||||
switch (t->ta_busspeed) {
|
||||
case TC_SPEED_25_MHZ:
|
||||
speed = ASC_SPEED_25_MHZ;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf(" (unknown TC speed, assuming 12.5MHz) ");
|
||||
/* FALLTHROUGH*/
|
||||
case TC_SPEED_12_5_MHZ:
|
||||
speed = ASC_SPEED_12_5_MHZ;
|
||||
break;
|
||||
};
|
||||
|
||||
ascattach(asc, bufsiz, speed);
|
||||
|
||||
/* tie pseudo-slot to device */
|
||||
tc_intr_establish(parent, t->ta_cookie, TC_IPL_BIO,
|
||||
asc_intr, asc);
|
||||
|
||||
printf(": target %d\n", asc->sc_id);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DMA handling routines. For a turbochannel device, just set the dmar.
|
||||
* For the I/O ASIC, handle the actual DMA interface.
|
||||
*/
|
||||
static void
|
||||
tc_dma_start(asc, state, cp, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
caddr_t cp;
|
||||
int flag;
|
||||
{
|
||||
|
||||
if (flag == ASCDMA_WRITE)
|
||||
*asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(cp);
|
||||
else
|
||||
*asc->dmar = ASC_DMA_ADDR(cp);
|
||||
}
|
||||
|
||||
static void
|
||||
tc_dma_end(asc, state, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
int flag;
|
||||
{
|
||||
|
||||
}
|
92
sys/dev/tc/ascvar.h
Normal file
92
sys/dev/tc/ascvar.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* $NetBSD: ascvar.h,v 1.1 1996/09/25 21:07:56 jonathan Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
* State kept for each active SCSI device.
|
||||
*/
|
||||
struct script;
|
||||
|
||||
typedef struct scsi_state {
|
||||
struct script *script; /* saved script while processing error */
|
||||
int statusByte; /* status byte returned during STATUS_PHASE */
|
||||
int error; /* errno to pass back to device driver */
|
||||
u_char *dmaBufAddr; /* DMA buffer address */
|
||||
u_int dmaBufSize; /* DMA buffer size */
|
||||
int dmalen; /* amount to transfer in this chunk */
|
||||
int dmaresid; /* amount not transfered if chunk suspended */
|
||||
int buflen; /* total remaining amount of data to transfer */
|
||||
char *buf; /* current pointer within scsicmd->buf */
|
||||
int flags; /* see below */
|
||||
int msglen; /* number of message bytes to read */
|
||||
int msgcnt; /* number of message bytes received */
|
||||
u_char sync_period; /* DMA synchronous period */
|
||||
u_char sync_offset; /* DMA synchronous xfer offset or 0 if async */
|
||||
u_char msg_out; /* next MSG_OUT byte to send */
|
||||
u_char msg_in[16]; /* buffer for multibyte messages */
|
||||
} State;
|
||||
|
||||
/* state flags */
|
||||
#define DISCONN 0x001 /* true if currently disconnected from bus */
|
||||
#define DMA_IN_PROGRESS 0x002 /* true if data DMA started */
|
||||
#define DMA_IN 0x004 /* true if reading from SCSI device */
|
||||
#define DMA_OUT 0x010 /* true if writing to SCSI device */
|
||||
#define DID_SYNC 0x020 /* true if synchronous offset was negotiated */
|
||||
#define TRY_SYNC 0x040 /* true if try neg. synchronous offset */
|
||||
#define PARITY_ERR 0x080 /* true if parity error seen */
|
||||
#define CHECK_SENSE 0x100 /* true if doing sense command */
|
||||
|
||||
|
||||
/*
|
||||
* State kept for each active SCSI host interface (53C94).
|
||||
*/
|
||||
|
||||
struct asc_softc {
|
||||
struct device sc_dev; /* us as a device */
|
||||
asc_regmap_t *regs; /* chip address */
|
||||
volatile int *dmar; /* DMA address register address */
|
||||
u_char *buff; /* RAM buffer address (uncached) */
|
||||
int sc_id; /* SCSI ID of this interface */
|
||||
int myidmask; /* ~(1 << myid) */
|
||||
int state; /* current SCSI connection state */
|
||||
int target; /* target SCSI ID if busy */
|
||||
struct script *script; /* next expected interrupt & action */
|
||||
ScsiCmd *cmd[ASC_NCMD]; /* active command indexed by SCSI ID */
|
||||
State st[ASC_NCMD]; /* state info for each active command */
|
||||
/* Start dma routine */
|
||||
void (*dma_start) __P((struct asc_softc *asc,
|
||||
struct scsi_state *state,
|
||||
caddr_t cp, int flag));
|
||||
/* End dma routine */
|
||||
void (*dma_end) __P((struct asc_softc *asc,
|
||||
struct scsi_state *state, int flag));
|
||||
|
||||
u_char *dma_next;
|
||||
int dma_xfer; /* Dma len still to go */
|
||||
int min_period; /* Min transfer period clk/byte */
|
||||
int max_period; /* Max transfer period clk/byte */
|
||||
int ccf; /* CCF, whatever that really is? */
|
||||
int timeout_250; /* 250ms timeout */
|
||||
int tb_ticks; /* 4ns. ticks/tb channel ticks */
|
||||
#ifdef USE_NEW_SCSI
|
||||
struct scsi_link sc_link; /* scsi link struct */
|
||||
#endif
|
||||
};
|
||||
typedef struct asc_softc *asc_softc_t;
|
||||
|
||||
#define ASC_STATE_IDLE 0 /* idle state */
|
||||
#define ASC_STATE_BUSY 1 /* selecting or currently connected */
|
||||
#define ASC_STATE_TARGET 2 /* currently selected as target */
|
||||
#define ASC_STATE_RESEL 3 /* currently waiting for reselect */
|
||||
|
||||
|
||||
#define ASC_SPEED_25_MHZ 250
|
||||
#define ASC_SPEED_12_5_MHZ 125
|
||||
|
||||
void ascattach __P((struct asc_softc *asc, int dmabufsiz, int bus_speed));
|
||||
int asc_intr __P ((void *asc));
|
||||
|
||||
/*
|
||||
* Dma operations.
|
||||
*/
|
||||
#define ASCDMA_READ 1
|
||||
#define ASCDMA_WRITE 2
|
Loading…
Reference in New Issue
Block a user