From ee0d232c6247e8570bd2a522de21626c1b00ab75 Mon Sep 17 00:00:00 2001 From: schodet Date: Thu, 1 May 2003 20:47:49 +0000 Subject: Import des sources du driver kernel pour le busp. --- 2003/i/buzz/src/kernel/pbus.c | 326 ++++++++++++++++++++++++++++++++++++++++++ 2003/i/buzz/src/kernel/pbus.h | 24 ++++ 2 files changed, 350 insertions(+) create mode 100644 2003/i/buzz/src/kernel/pbus.c create mode 100644 2003/i/buzz/src/kernel/pbus.h (limited to '2003/i') diff --git a/2003/i/buzz/src/kernel/pbus.c b/2003/i/buzz/src/kernel/pbus.c new file mode 100644 index 0000000..277428a --- /dev/null +++ b/2003/i/buzz/src/kernel/pbus.c @@ -0,0 +1,326 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* autoconfig stuff... */ + +#define BUFSZ (256<<10) +#define DMASIZE (2*BUFSZ) + +struct pbus_softc { + struct device sc_dev; /* REQUIRED first entry */ + void *sc_ih; /* interrupt handle */ + bus_space_tag_t iot; + bus_space_handle_t ioh; + bus_dma_tag_t dmat; + unsigned long iobase; + bus_dmamap_t sc_dmam; /* bus dma map */ + unsigned char *sc_cpudma; /* dma memory space from cpu space*/ + unsigned long sc_bonitodma; /* dma memory space from pci space*/ + unsigned long sc_dmasize; /* dma buffer size */ + struct proc *cproc; /* Control process */ + int csignal; /* Control signal */ + int in_dma; + int buf_ok; + int framesize; + int buf_consumed; + int pbusinten; +}; + +static int pbusprobe(struct device *, struct cfdata *, void *); +static void pbusattach(struct device *, struct device *, void *); + +struct cfattach pbus_ca = { + sizeof(struct pbus_softc), pbusprobe, pbusattach +}; + +#define BUFSYNC_PRE \ + bus_dmamap_sync(sc->dmat,sc->sc_dmam,0,DMASIZE,BUS_DMASYNC_PREREAD) +#define BUFSYNC_POST \ + bus_dmamap_sync(sc->dmat,sc->sc_dmam,0,DMASIZE,BUS_DMASYNC_POSTREAD) + +#define PBUS_WRITE_4(reg, val) \ + bus_space_write_4(sc->iot, sc->ioh, reg, val) +#define PBUS_READ_4(reg) \ + bus_space_read_4(sc->iot, sc->ioh, reg) + +static int +pbusprobe(struct device *parent, struct cfdata *cf, void *aux) +{ + struct bonito_io_attach *bia = aux; + struct pbus_softc scp; + struct pbus_softc *sc=&scp; + sc->iobase=bia->base; + + return 1; +} + +int pbus_intr(void *p); + +static void +pbusattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + bus_dma_segment_t seg; + int rseg; + struct bonito_io_attach *bia = aux; + struct pbus_softc *sc = (struct pbus_softc *)self; + + sc->iot=bia->iot; + sc->dmat=bia->dmat; + bus_space_map(sc->iot, bia->base, 12, 0, &(sc->ioh)); + + sc->iobase=(unsigned long)sc->ioh; + printf("\n"); + + + PBUS_WRITE_4(0x08,PBUS_RnW|PBUS_CLK); + PBUS_WRITE_4(0x0,0); + sc->sc_dmasize=DMASIZE; + sc->in_dma=0; + sc->buf_ok=0; + sc->framesize=BUFSZ; + sc->csignal=SIGUSR1; + sc->pbusinten=0; + sc->buf_consumed=0; + + /* + * Allocate a DMA area for the card. + */ + if (bus_dmamem_alloc(sc->dmat, sc->sc_dmasize, NBPG, 0, &seg, 1, + &rseg, BUS_DMA_NOWAIT|BUS_DMA_DIRECT)) + { + printf("%s: couldn't allocate DMA\n", + sc->sc_dev.dv_xname); + return; + } + if (bus_dmamem_map(sc->dmat, &seg, rseg, sc->sc_dmasize, + (caddr_t *)&sc->sc_cpudma, + BUS_DMA_NOWAIT|BUS_DMA_DIRECT)) + { + printf("%s: couldn't map DMA\n", + sc->sc_dev.dv_xname); + return; + } + + /* + * Create and load the DMA map for the DMA area. + */ + if (bus_dmamap_create(sc->dmat, sc->sc_dmasize, 1, + sc->sc_dmasize, 0, BUS_DMA_NOWAIT|BUS_DMA_DIRECT, &sc->sc_dmam)) + { + printf("%s: couldn't create DMA map\n", + sc->sc_dev.dv_xname); + bus_dmamem_free(sc->dmat, &seg, rseg); + return; + } + if (bus_dmamap_load(sc->dmat, sc->sc_dmam, + sc->sc_cpudma, sc->sc_dmasize, NULL, BUS_DMA_NOWAIT|BUS_DMA_DIRECT)) + { + printf("%s: coundn't load DMA map\n", + sc->sc_dev.dv_xname); + bus_dmamem_free(sc->dmat, &seg, rseg); + return; + } + + sc->sc_bonitodma = sc->sc_dmam->dm_segs[0].ds_addr; + bzero(sc->sc_cpudma,DMASIZE); + + sc->sc_ih = bonito_intr_establish(bia->irq, IPL_NET, pbus_intr, sc); + if (sc->sc_ih == NULL) + { + printf("%s: couldn't establish interrupt at %d\n", + sc->sc_dev.dv_xname,bia->irq); + return; + } + + printf("%s: DMA map:0x%08lx (PHYS:0x%08lx)\n", sc->sc_dev.dv_xname, (unsigned long) sc->sc_cpudma, sc->sc_bonitodma); + printf("%s: interrupting at %d\n", sc->sc_dev.dv_xname, bia->irq); + +} + + + +/* + * operational routines: + * open, close, read, write, + * ioctl, mmap + */ + +dev_type_open(pbusopen); +dev_type_close(pbusclose); +dev_type_read(pbusread); +dev_type_write(pbuswrite); +dev_type_ioctl(pbusioctl); +dev_type_mmap(pbusmmap); + +int +pbusopen(dev, flag, fmt, proc) + dev_t dev; + int flag, fmt; + struct proc *proc; +{ + struct pbus_softc *sc= pbus_cd.cd_devs[0]; + + if (minor(dev)==1) /* PBUS */ + sc->cproc=proc; + return 0; +} + +int +pbusclose(dev, flag, fmt, proc) + dev_t dev; + int flag, fmt; + struct proc *proc; +{ + struct pbus_softc *sc= pbus_cd.cd_devs[0]; + if (minor(dev)==1) /* PBUS */ + sc->cproc=NULL; + return 0; +} + +int +pbusread(dev, uio, flags) + dev_t dev; + struct uio *uio; + int flags; +{ + int bufok,remain; + int resid=uio->uio_resid; + int s; + struct pbus_softc *sc= pbus_cd.cd_devs[0]; + s=splhigh(); + bufok=*((volatile int *)(&sc->buf_ok)); + if ((!bufok)&&(!sc->in_dma)) + { + BUFSYNC_PRE; + PBUS_WRITE_4(0x4,sc->sc_bonitodma); + sc->in_dma=1; + } + splx(s); + if (!bufok) return 0; + remain=sc->framesize-sc->buf_consumed; + if (resid>remain) resid=remain; + + uiomove(sc->sc_cpudma+sc->buf_consumed,resid,uio); + sc->buf_consumed+=resid; + remain-=resid; + if (!remain) + { + sc->buf_consumed=0; + sc->buf_ok=0; + } + return 0; +} + +int +pbuswrite(dev, uio, flags) + dev_t dev; + struct uio *uio; + int flags; +{ + return ENODEV; +} + +int pbus_intr(void *p) +{ + struct pbus_softc *sc = (struct pbus_softc *)p; + unsigned long status=PBUS_READ_4(0); + if (status&0x20000000) + { + PBUS_WRITE_4(8,PBUS_READ_4(8)&0x3FFF); + if (sc->cproc!=NULL) psignal(sc->cproc,sc->csignal); + } + else + { + if (status&0x40000000) + { + /* Frame Ok */ + BUFSYNC_POST; + sc->buf_ok=1; + sc->in_dma=0; + } + else + { + /* Pointer slot avail */ + } + } + return 0; +} + +#define PBUS_WAIT \ + tsleep(sc,PUSER | PCATCH,"pbusio",(HZ/10000)?(HZ/10000):1) + +int +pbusioctl(dev, cmd, addr, flag, proc) + dev_t dev; + u_long cmd; + int flag; + caddr_t addr; + struct proc *proc; +{ + struct pbus_softc *sc= pbus_cd.cd_devs[0]; + struct pbus_io *parm=(struct pbus_io *)addr; + unsigned long *fsize=(unsigned long *)addr; + /* PBUS IOctl */ + if (minor(dev)==1) /* PBUS */ + { + switch (cmd) + { + case PBUS_READ: + PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|PBUS_RnW|sc->pbusinten); + PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_RnW|sc->pbusinten); + PBUS_WAIT; + parm->data=PBUS_READ_4(8)&0xFF; + PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|PBUS_RnW|sc->pbusinten); + PBUS_WAIT; + break; + case PBUS_WRITE: + PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|(parm->data)|sc->pbusinten); + PBUS_WRITE_4(8,(parm->addr<<8)|(parm->data)|sc->pbusinten); + PBUS_WAIT; + PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|(parm->data)|sc->pbusinten); + PBUS_WAIT; + PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|PBUS_RnW|sc->pbusinten); + break; + case PBUS_INTENABLE: + sc->pbusinten=1; + PBUS_WRITE_4(8,0|PBUS_CLK|PBUS_RnW|sc->pbusinten); + break; + } + parm->ints=(~(PBUS_READ_4(8)>>16))&0x1F; + } + + if (minor(dev)==0) /* CAM */ + { + switch (cmd) + { + case CAM_SETFRAMESIZE: + PBUS_WRITE_4(0x0,1); + sc->framesize=*fsize; + break; + } + } + + return 0; +} + +paddr_t +pbusmmap(dev_t dev, off_t offset, int nprot) +{ + return ENXIO; +} + + diff --git a/2003/i/buzz/src/kernel/pbus.h b/2003/i/buzz/src/kernel/pbus.h new file mode 100644 index 0000000..7b11499 --- /dev/null +++ b/2003/i/buzz/src/kernel/pbus.h @@ -0,0 +1,24 @@ +#ifndef _PBUS_H_ +#define _PBUS_H_ + +#include + +struct pbus_io +{ + unsigned char addr; /* Address */ + unsigned char data; /* Data */ + unsigned char ints; /* IRQ lines */ +}; + +#define PBUS_DATAMASK 0x00FF +#define PBUS_ADDRMASK 0x0F00 +#define PBUS_RnW 0x1000 +#define PBUS_CLK 0x2000 +#define PBUS_INTEN 0x4000 + +#define PBUS_READ _IOWR('R', 1, struct pbus_io) +#define PBUS_WRITE _IOWR('R', 2, struct pbus_io) +#define PBUS_INTENABLE _IO('R', 3) + +#define CAM_SETFRAMESIZE _IOW('R', 10, unsigned long) +#endif -- cgit v1.2.3