/* $NetBSD: asc_tc.c,v 1.2 1996/10/10 20:25:35 christos 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 #include #include #include #include #include #include #include /* XXX */ #include /* XXX */ #include /* XXX */ #include /*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. */ kprintf(" (bus speed: %d) ", t->ta_busspeed); switch (t->ta_busspeed) { case TC_SPEED_25_MHZ: speed = ASC_SPEED_25_MHZ; break; default: kprintf(" (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); kprintf(": 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; { }