1996-10-13 05:37:04 +04:00
|
|
|
/* $NetBSD: asc_tc.c,v 1.4 1996/10/13 01:38:37 christos Exp $ */
|
1996-09-26 01:07:46 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
1996-10-13 05:37:04 +04:00
|
|
|
printf(" (bus speed: %d) ", t->ta_busspeed);
|
1996-09-26 01:07:46 +04:00
|
|
|
|
|
|
|
switch (t->ta_busspeed) {
|
|
|
|
case TC_SPEED_25_MHZ:
|
|
|
|
speed = ASC_SPEED_25_MHZ;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
1996-10-13 05:37:04 +04:00
|
|
|
printf(" (unknown TC speed, assuming 12.5MHz) ");
|
1996-09-26 01:07:46 +04:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|