Init
This commit is contained in:
235
sys/sbusdev/dmaga.c
Normal file
235
sys/sbusdev/dmaga.c
Normal file
@@ -0,0 +1,235 @@
|
||||
#ident "@(#)dmaga.c 1.1"
|
||||
/* @(#)dmaga.c 1.1 94/10/31 SMI */
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include "dma.h"
|
||||
#if NDMA > 0
|
||||
/*
|
||||
* Sbus DMA gate array 'driver'
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/debug.h>
|
||||
#include <sundev/mbvar.h>
|
||||
|
||||
#include <sun/autoconf.h>
|
||||
#include <sbusdev/dmaga.h>
|
||||
#include <machine/mmu.h>
|
||||
|
||||
static int dmaintr();
|
||||
|
||||
int ndma_map = 0;
|
||||
struct dma_map {
|
||||
struct dmaga *regs;
|
||||
int bustype;
|
||||
addr_t addr;
|
||||
char free;
|
||||
} *dma_map;
|
||||
|
||||
static int dmaidentify(), dmaattach();
|
||||
struct dev_ops dma_ops = {
|
||||
1,
|
||||
dmaidentify,
|
||||
dmaattach
|
||||
};
|
||||
|
||||
#ifdef GASP
|
||||
/*
|
||||
* This code for GASP cards (that have no prom)
|
||||
*/
|
||||
|
||||
/*
|
||||
* GASP cards can be in slot 1, slot 1 + 0x1000000,
|
||||
* slot 2, slot 2 + 0x2000000
|
||||
*/
|
||||
|
||||
int gasp_cards = 0;
|
||||
|
||||
#define GASP_OFFSET 0x1000000
|
||||
u_long gasp_addrs[4] = {
|
||||
SBUS_BASE+SBUS_SIZE,
|
||||
SBUS_BASE+SBUS_SIZE+GASP_OFFSET,
|
||||
SBUS_BASE+(SBUS_SIZE<<1),
|
||||
SBUS_BASE+(SBUS_SIZE<<1)+GASP_OFFSET
|
||||
};
|
||||
|
||||
|
||||
#include <machine/pte.h>
|
||||
|
||||
#define DMA_OFFSET 0x400000
|
||||
#define Dma_addr(card) (gasp_addrs[(card)] + DMA_OFFSET)
|
||||
|
||||
static void
|
||||
new_dma(prev, gaddr)
|
||||
struct dev_info *prev;
|
||||
u_long gaddr;
|
||||
{
|
||||
struct dev_info *dev;
|
||||
auto long tmp;
|
||||
|
||||
dev = (struct dev_info *) kmem_zalloc (sizeof (*dev));
|
||||
dev->devi_parent = prev->devi_parent;
|
||||
dev->devi_next = prev->devi_next;
|
||||
prev->devi_next = dev;
|
||||
dev->devi_name = prev->devi_name;
|
||||
dev->devi_nreg = 1;
|
||||
dev->devi_reg = (struct dev_reg *)
|
||||
kmem_zalloc(sizeof (struct dev_reg));
|
||||
dev->devi_reg->reg_bustype = OBIO;
|
||||
dev->devi_reg->reg_addr = (addr_t) gaddr;
|
||||
dev->devi_reg->reg_size = sizeof (struct dmaga);
|
||||
dev->devi_driver = &dma_ops;
|
||||
dev->devi_nodeid = prev->devi_nodeid; /* lies. all lies */
|
||||
#if defined(DEVINFO_DEBUG)
|
||||
printf("new_dma() constructed a devinfo node\n");
|
||||
#endif
|
||||
ndma_map += 1;
|
||||
|
||||
}
|
||||
#endif GASP
|
||||
|
||||
|
||||
static int
|
||||
dmaidentify(name)
|
||||
char *name;
|
||||
{
|
||||
if (strcmp(name, "dma") == 0) {
|
||||
ndma_map++;
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static int
|
||||
dmaattach(dev)
|
||||
register struct dev_info *dev;
|
||||
{
|
||||
register struct dma_map *dp;
|
||||
static char unit_no = 0;
|
||||
|
||||
#ifdef GASP
|
||||
if (unit_no == 0) {
|
||||
register card;
|
||||
struct dev_info *tmp = dev;
|
||||
for (card = 0; card < 4; card++) {
|
||||
if (gasp_cards & (1<<card)) {
|
||||
new_dma(tmp, Dma_addr(card));
|
||||
tmp = tmp->devi_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif GASP
|
||||
|
||||
if (!dma_map) {
|
||||
dma_map = (struct dma_map *)
|
||||
kmem_alloc((u_int) (sizeof (struct dma_map) * ndma_map));
|
||||
if (!dma_map) {
|
||||
printf("dma%d: No space for dma_map structure\n",
|
||||
dev->devi_unit);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((dev->devi_unit = unit_no++) >= ndma_map) {
|
||||
printf("dma%d: bad unit number\n", dev->devi_unit);
|
||||
return (-1);
|
||||
} else
|
||||
dp = &dma_map[dev->devi_unit];
|
||||
|
||||
if (dev->devi_nreg > 1) {
|
||||
printf("dma%d: bad register specification\n", dev->devi_unit);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/* map in the device registers */
|
||||
dp->regs = (struct dmaga *)
|
||||
map_regs(dev->devi_reg->reg_addr, dev->devi_reg->reg_size,
|
||||
dev->devi_reg->reg_bustype);
|
||||
if (dp->regs == (struct dmaga *) 0) {
|
||||
printf("dma%d: unable to map registers\n", dev->devi_unit);
|
||||
return (-1);
|
||||
}
|
||||
dp->bustype = dev->devi_reg->reg_bustype;
|
||||
dp->addr = dev->devi_reg->reg_addr;
|
||||
dp->free = 1;
|
||||
if (dev->devi_nintr) {
|
||||
addintr(dev->devi_intr->int_pri, dmaintr,
|
||||
dev->devi_name, dev->devi_unit);
|
||||
}
|
||||
report_dev(dev);
|
||||
attach_devs(dev);
|
||||
#ifdef GASP
|
||||
if (dev->devi_unit == 0 && ndma_map > 1) {
|
||||
int slot;
|
||||
for (slot = 1; slot < ndma_map; slot++) {
|
||||
dev = dev->devi_next;
|
||||
(void) dmaattach(dev);
|
||||
}
|
||||
}
|
||||
#endif GASP
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef SBUS_SIZE
|
||||
/*
|
||||
* If SBUS_SIZE is provided, then we just consider the PArange as
|
||||
* divided up into hunks the size of the S-Bus, and this macro returns
|
||||
* which one it is. It may not really correspond to the slot, but is
|
||||
* OK for use in dma_alloc. Otherwise, a function sbusslot() must be
|
||||
* available that gives the slot number from the low 32 bits of the
|
||||
* paddr.
|
||||
*/
|
||||
#define sbusslot(pa) (((int)(pa))/SBUS_SIZE)
|
||||
#endif
|
||||
|
||||
struct dmaga *
|
||||
dma_alloc(bustype, addr)
|
||||
register int bustype;
|
||||
register addr_t addr;
|
||||
{
|
||||
register i;
|
||||
register struct dma_map *dp = dma_map;
|
||||
|
||||
for (i = 0; i < ndma_map; i++) {
|
||||
if ((dp->free && (dp->bustype == bustype)) &&
|
||||
(sbusslot((unsigned) dp->addr) == sbusslot((unsigned) addr))) {
|
||||
dp->free = 0;
|
||||
return (dp->regs);
|
||||
}
|
||||
dp++;
|
||||
}
|
||||
return ((struct dmaga *) 0);
|
||||
}
|
||||
|
||||
void
|
||||
dma_free(regs)
|
||||
struct dmaga *regs;
|
||||
{
|
||||
register i;
|
||||
register struct dma_map *dp = dma_map;
|
||||
|
||||
for (i = 0; i < ndma_map; i++) {
|
||||
if (!(dp->free) && dp->regs == regs) {
|
||||
dp->free = 1;
|
||||
break;
|
||||
}
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dmaintr()
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif NDMA > 0
|
||||
Reference in New Issue
Block a user