Allocate DMA bounce buffers only when requested by drivers. Only the
fd and wt drivers need bounce buffers, so this normally saves 32K-1K of kernel memory. Keep track of which DMA channels are busy. isa_dmadone() must now be called when DMA has finished or been aborted. Panic for unallocated and too-small (required) bounce buffers. fd.c: There will be new warnings about isa_dmadone() not being called after DMA has been aborted. sound/dmabuf.c: isa_dmadone() needs more parameters than are available, so temporarily use a new interface isa_dmadone_nobounce() to avoid having to worry about panics for fake parameters. Untested.
This commit is contained in:
parent
e7973e6070
commit
dd87702a51
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
|
||||
* $Id: machdep.c,v 1.171 1996/01/21 20:57:03 joerg Exp $
|
||||
* $Id: machdep.c,v 1.172 1996/01/23 02:39:12 davidg Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -400,14 +400,6 @@ again:
|
||||
*/
|
||||
vm_bounce_init();
|
||||
#endif
|
||||
/*
|
||||
* XXX allocate a contiguous area for ISA (non busmaster) DMA
|
||||
* operations. This _should_ only be done if the DMA channels
|
||||
* will actually be used, but for now we do it always.
|
||||
*/
|
||||
#define DMAPAGES 8
|
||||
isaphysmem =
|
||||
vm_page_alloc_contig(DMAPAGES * PAGE_SIZE, 0, 0xfffffful, 64*1024);
|
||||
|
||||
printf("avail memory = %d (%dK bytes)\n", ptoa(cnt.v_free_count),
|
||||
ptoa(cnt.v_free_count) / 1024);
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: md_var.h,v 1.4 1995/09/03 05:43:25 julian Exp $
|
||||
* $Id: md_var.h,v 1.5 1995/11/21 12:52:57 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_MD_VAR_H_
|
||||
@ -42,7 +42,6 @@ extern u_long cpu_high;
|
||||
extern u_long cpu_id;
|
||||
extern char cpu_vendor[];
|
||||
extern char etext[];
|
||||
extern vm_offset_t isaphysmem;
|
||||
extern char kstack[];
|
||||
extern void (*netisrs[32]) __P((void));
|
||||
extern int nfs_diskless_valid;
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: isa.c,v 1.61 1996/01/19 23:38:06 phk Exp $
|
||||
* $Id: isa.c,v 1.62 1996/01/27 01:56:30 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -561,16 +561,46 @@ isa_defaultirq()
|
||||
outb(IO_ICU2, 0x0a); /* default to IRR on read */
|
||||
}
|
||||
|
||||
/* region of physical memory known to be contiguous */
|
||||
vm_offset_t isaphysmem;
|
||||
static caddr_t dma_bounce[8]; /* XXX */
|
||||
static char bounced[8]; /* XXX */
|
||||
#define MAXDMASZ 512 /* XXX */
|
||||
static caddr_t dma_bouncebuf[8];
|
||||
static unsigned dma_bouncebufsize[8];
|
||||
static char dma_bounced[8];
|
||||
static char dma_busy[8];
|
||||
|
||||
/* high byte of address is stored in this port for i-th dma channel */
|
||||
static short dmapageport[8] =
|
||||
{ 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
|
||||
|
||||
/*
|
||||
* Allocate a DMA channel.
|
||||
*/
|
||||
void
|
||||
isa_dmainit(chan, bouncebufsize)
|
||||
unsigned chan;
|
||||
unsigned bouncebufsize;
|
||||
{
|
||||
void *buf;
|
||||
|
||||
if (chan > 7 || dma_bouncebuf[chan] != NULL)
|
||||
panic("isa_dmainit: impossible request");
|
||||
dma_bouncebufsize[chan] = bouncebufsize;
|
||||
|
||||
/* Try malloc() first. It works better if it works. */
|
||||
buf = malloc(bouncebufsize, M_DEVBUF, M_NOWAIT);
|
||||
if (buf != NULL) {
|
||||
if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) {
|
||||
dma_bouncebuf[chan] = buf;
|
||||
return;
|
||||
}
|
||||
free(buf, M_DEVBUF);
|
||||
}
|
||||
buf = contigmalloc(bouncebufsize, M_DEVBUF, M_NOWAIT, 0ul, 0xfffffful,
|
||||
1ul, chan & 4 ? 0x20000ul : 0x10000ul);
|
||||
if (buf == NULL)
|
||||
printf("isa_dmainit(%d, %d) failed\n", chan, bouncebufsize);
|
||||
else
|
||||
dma_bouncebuf[chan] = buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* isa_dmacascade(): program 8237 DMA controller channel to accept
|
||||
* external dma control by a board.
|
||||
@ -604,13 +634,15 @@ void isa_dmastart(int flags, caddr_t addr, unsigned nbytes, unsigned chan)
|
||||
|| (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1)))
|
||||
panic("isa_dmastart: impossible request");
|
||||
|
||||
if (dma_busy[chan])
|
||||
printf("isa_dmastart: channel %u busy\n", chan);
|
||||
dma_busy[chan] = 1;
|
||||
if (isa_dmarangecheck(addr, nbytes, chan)) {
|
||||
if (dma_bounce[chan] == 0)
|
||||
dma_bounce[chan] =
|
||||
(caddr_t) isaphysmem + NBPG*chan;
|
||||
bounced[chan] = 1;
|
||||
newaddr = dma_bounce[chan];
|
||||
*(int *) newaddr = 0; /* XXX */
|
||||
if (dma_bouncebuf[chan] == NULL
|
||||
|| dma_bouncebufsize[chan] < nbytes)
|
||||
panic("isa_dmastart: bad bounce buffer");
|
||||
dma_bounced[chan] = 1;
|
||||
newaddr = dma_bouncebuf[chan];
|
||||
|
||||
/* copy bounce buffer on write */
|
||||
if (!(flags & B_READ))
|
||||
@ -694,12 +726,30 @@ void isa_dmastart(int flags, caddr_t addr, unsigned nbytes, unsigned chan)
|
||||
void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
|
||||
{
|
||||
|
||||
/* copy bounce buffer on read */
|
||||
/*if ((flags & (B_PHYS|B_READ)) == (B_PHYS|B_READ))*/
|
||||
if (bounced[chan]) {
|
||||
bcopy(dma_bounce[chan], addr, nbytes);
|
||||
bounced[chan] = 0;
|
||||
if (!dma_busy[chan])
|
||||
printf("isa_dmadone: channel %d not busy\n", chan);
|
||||
if (dma_bounced[chan]) {
|
||||
/* copy bounce buffer on read */
|
||||
if (flags & B_READ)
|
||||
bcopy(dma_bouncebuf[chan], addr, nbytes);
|
||||
|
||||
dma_bounced[chan] = 0;
|
||||
}
|
||||
dma_busy[chan] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
isa_dmadone_nobounce(chan)
|
||||
unsigned chan;
|
||||
{
|
||||
|
||||
if (!dma_busy[chan])
|
||||
printf("isa_dmadone_nobounce: channel %u not busy\n", chan);
|
||||
if (dma_bounced[chan]) {
|
||||
printf("isa_dmadone_nobounce: channel %u bounced\n", chan);
|
||||
dma_bounced[chan] = 0;
|
||||
}
|
||||
dma_busy[chan] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -43,7 +43,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
||||
* $Id: fd.c,v 1.76 1995/12/10 13:38:29 phk Exp $
|
||||
* $Id: fd.c,v 1.77 1995/12/10 19:44:45 bde Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -574,6 +574,7 @@ fdattach(struct isa_device *dev)
|
||||
fdc->fdcu = fdcu;
|
||||
fdc->flags |= FDC_ATTACHED;
|
||||
fdc->dmachan = dev->id_drq;
|
||||
isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
|
||||
fdc->state = DEVIDLE;
|
||||
/* reset controller, turn motor off, clear fdout mirror reg */
|
||||
outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
|
||||
* $Id: machdep.c,v 1.171 1996/01/21 20:57:03 joerg Exp $
|
||||
* $Id: machdep.c,v 1.172 1996/01/23 02:39:12 davidg Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -400,14 +400,6 @@ again:
|
||||
*/
|
||||
vm_bounce_init();
|
||||
#endif
|
||||
/*
|
||||
* XXX allocate a contiguous area for ISA (non busmaster) DMA
|
||||
* operations. This _should_ only be done if the DMA channels
|
||||
* will actually be used, but for now we do it always.
|
||||
*/
|
||||
#define DMAPAGES 8
|
||||
isaphysmem =
|
||||
vm_page_alloc_contig(DMAPAGES * PAGE_SIZE, 0, 0xfffffful, 64*1024);
|
||||
|
||||
printf("avail memory = %d (%dK bytes)\n", ptoa(cnt.v_free_count),
|
||||
ptoa(cnt.v_free_count) / 1024);
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: md_var.h,v 1.4 1995/09/03 05:43:25 julian Exp $
|
||||
* $Id: md_var.h,v 1.5 1995/11/21 12:52:57 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_MD_VAR_H_
|
||||
@ -42,7 +42,6 @@ extern u_long cpu_high;
|
||||
extern u_long cpu_id;
|
||||
extern char cpu_vendor[];
|
||||
extern char etext[];
|
||||
extern vm_offset_t isaphysmem;
|
||||
extern char kstack[];
|
||||
extern void (*netisrs[32]) __P((void));
|
||||
extern int nfs_diskless_valid;
|
||||
|
@ -43,7 +43,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
||||
* $Id: fd.c,v 1.76 1995/12/10 13:38:29 phk Exp $
|
||||
* $Id: fd.c,v 1.77 1995/12/10 19:44:45 bde Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -574,6 +574,7 @@ fdattach(struct isa_device *dev)
|
||||
fdc->fdcu = fdcu;
|
||||
fdc->flags |= FDC_ATTACHED;
|
||||
fdc->dmachan = dev->id_drq;
|
||||
isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
|
||||
fdc->state = DEVIDLE;
|
||||
/* reset controller, turn motor off, clear fdout mirror reg */
|
||||
outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: isa.c,v 1.61 1996/01/19 23:38:06 phk Exp $
|
||||
* $Id: isa.c,v 1.62 1996/01/27 01:56:30 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -561,16 +561,46 @@ isa_defaultirq()
|
||||
outb(IO_ICU2, 0x0a); /* default to IRR on read */
|
||||
}
|
||||
|
||||
/* region of physical memory known to be contiguous */
|
||||
vm_offset_t isaphysmem;
|
||||
static caddr_t dma_bounce[8]; /* XXX */
|
||||
static char bounced[8]; /* XXX */
|
||||
#define MAXDMASZ 512 /* XXX */
|
||||
static caddr_t dma_bouncebuf[8];
|
||||
static unsigned dma_bouncebufsize[8];
|
||||
static char dma_bounced[8];
|
||||
static char dma_busy[8];
|
||||
|
||||
/* high byte of address is stored in this port for i-th dma channel */
|
||||
static short dmapageport[8] =
|
||||
{ 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
|
||||
|
||||
/*
|
||||
* Allocate a DMA channel.
|
||||
*/
|
||||
void
|
||||
isa_dmainit(chan, bouncebufsize)
|
||||
unsigned chan;
|
||||
unsigned bouncebufsize;
|
||||
{
|
||||
void *buf;
|
||||
|
||||
if (chan > 7 || dma_bouncebuf[chan] != NULL)
|
||||
panic("isa_dmainit: impossible request");
|
||||
dma_bouncebufsize[chan] = bouncebufsize;
|
||||
|
||||
/* Try malloc() first. It works better if it works. */
|
||||
buf = malloc(bouncebufsize, M_DEVBUF, M_NOWAIT);
|
||||
if (buf != NULL) {
|
||||
if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) {
|
||||
dma_bouncebuf[chan] = buf;
|
||||
return;
|
||||
}
|
||||
free(buf, M_DEVBUF);
|
||||
}
|
||||
buf = contigmalloc(bouncebufsize, M_DEVBUF, M_NOWAIT, 0ul, 0xfffffful,
|
||||
1ul, chan & 4 ? 0x20000ul : 0x10000ul);
|
||||
if (buf == NULL)
|
||||
printf("isa_dmainit(%d, %d) failed\n", chan, bouncebufsize);
|
||||
else
|
||||
dma_bouncebuf[chan] = buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* isa_dmacascade(): program 8237 DMA controller channel to accept
|
||||
* external dma control by a board.
|
||||
@ -604,13 +634,15 @@ void isa_dmastart(int flags, caddr_t addr, unsigned nbytes, unsigned chan)
|
||||
|| (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1)))
|
||||
panic("isa_dmastart: impossible request");
|
||||
|
||||
if (dma_busy[chan])
|
||||
printf("isa_dmastart: channel %u busy\n", chan);
|
||||
dma_busy[chan] = 1;
|
||||
if (isa_dmarangecheck(addr, nbytes, chan)) {
|
||||
if (dma_bounce[chan] == 0)
|
||||
dma_bounce[chan] =
|
||||
(caddr_t) isaphysmem + NBPG*chan;
|
||||
bounced[chan] = 1;
|
||||
newaddr = dma_bounce[chan];
|
||||
*(int *) newaddr = 0; /* XXX */
|
||||
if (dma_bouncebuf[chan] == NULL
|
||||
|| dma_bouncebufsize[chan] < nbytes)
|
||||
panic("isa_dmastart: bad bounce buffer");
|
||||
dma_bounced[chan] = 1;
|
||||
newaddr = dma_bouncebuf[chan];
|
||||
|
||||
/* copy bounce buffer on write */
|
||||
if (!(flags & B_READ))
|
||||
@ -694,12 +726,30 @@ void isa_dmastart(int flags, caddr_t addr, unsigned nbytes, unsigned chan)
|
||||
void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
|
||||
{
|
||||
|
||||
/* copy bounce buffer on read */
|
||||
/*if ((flags & (B_PHYS|B_READ)) == (B_PHYS|B_READ))*/
|
||||
if (bounced[chan]) {
|
||||
bcopy(dma_bounce[chan], addr, nbytes);
|
||||
bounced[chan] = 0;
|
||||
if (!dma_busy[chan])
|
||||
printf("isa_dmadone: channel %d not busy\n", chan);
|
||||
if (dma_bounced[chan]) {
|
||||
/* copy bounce buffer on read */
|
||||
if (flags & B_READ)
|
||||
bcopy(dma_bouncebuf[chan], addr, nbytes);
|
||||
|
||||
dma_bounced[chan] = 0;
|
||||
}
|
||||
dma_busy[chan] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
isa_dmadone_nobounce(chan)
|
||||
unsigned chan;
|
||||
{
|
||||
|
||||
if (!dma_busy[chan])
|
||||
printf("isa_dmadone_nobounce: channel %u not busy\n", chan);
|
||||
if (dma_bounced[chan]) {
|
||||
printf("isa_dmadone_nobounce: channel %u bounced\n", chan);
|
||||
dma_bounced[chan] = 0;
|
||||
}
|
||||
dma_busy[chan] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -946,11 +946,14 @@ DMAbuf_close_dma (int dev)
|
||||
void
|
||||
DMAbuf_reset_dma (int dev)
|
||||
{
|
||||
#if 0
|
||||
int chan = audio_devs[dev]->dmachan;
|
||||
|
||||
#if 0
|
||||
disable_dma (chan);
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
isa_dmadone_nobounce(chan);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ALLOW_SELECT
|
||||
|
@ -19,7 +19,7 @@
|
||||
* the original CMU copyright notice.
|
||||
*
|
||||
* Version 1.3, Thu Nov 11 12:09:13 MSK 1993
|
||||
* $Id: wt.c,v 1.27 1995/12/22 15:39:45 bde Exp $
|
||||
* $Id: wt.c,v 1.28 1996/01/08 12:46:14 joerg Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -293,6 +293,7 @@ wtattach (struct isa_device *id)
|
||||
t->flags = TPSTART; /* tape is rewound */
|
||||
t->dens = -1; /* unknown density */
|
||||
kdc_wt[id->id_unit].kdc_state = DC_IDLE;
|
||||
isa_dmainit(t->chan, 1024);
|
||||
|
||||
#ifdef DEVFS
|
||||
sprintf(name,"rwt%d",id->id_unit);
|
||||
|
@ -43,7 +43,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
||||
* $Id: fd.c,v 1.76 1995/12/10 13:38:29 phk Exp $
|
||||
* $Id: fd.c,v 1.77 1995/12/10 19:44:45 bde Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -574,6 +574,7 @@ fdattach(struct isa_device *dev)
|
||||
fdc->fdcu = fdcu;
|
||||
fdc->flags |= FDC_ATTACHED;
|
||||
fdc->dmachan = dev->id_drq;
|
||||
isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
|
||||
fdc->state = DEVIDLE;
|
||||
/* reset controller, turn motor off, clear fdout mirror reg */
|
||||
outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user