mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-04 09:09:56 +00:00
Support bounce buffers for ISA DMA on the alpha. This is required for the
irongate chipset (used in the UP1000) which does not support scatter/gather DMA. We'll still use scatter gather if the core logic chipset supports it. Reviewed by: dfr
This commit is contained in:
parent
a40e8e8ba4
commit
49c0f52e11
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=61825
@ -240,7 +240,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
|
||||
|
||||
error = 0;
|
||||
|
||||
if (dmat->flags & BUS_DMA_ISA) {
|
||||
if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) {
|
||||
bus_dmamap_t map;
|
||||
map = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF,
|
||||
M_NOWAIT);
|
||||
@ -290,10 +290,12 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
|
||||
panic("bus_dmamap_create: page reallocation "
|
||||
"not implemented");
|
||||
}
|
||||
pages = atop(dmat->maxsize);
|
||||
pages = atop(dmat->maxsize) + 1;
|
||||
pages = MIN(maxpages - total_bpages, pages);
|
||||
error = alloc_bounce_pages(dmat, pages);
|
||||
|
||||
if (alloc_bounce_pages(dmat, pages) < pages)
|
||||
error = ENOMEM;
|
||||
|
||||
if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) {
|
||||
if (error == 0)
|
||||
dmat->flags |= BUS_DMA_MIN_ALLOC_COMP;
|
||||
@ -316,7 +318,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
|
||||
int
|
||||
bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
|
||||
{
|
||||
if (dmat->flags & BUS_DMA_ISA) {
|
||||
if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) {
|
||||
sgmap_free_region(chipset.sgmap, map->sgmaphandle);
|
||||
}
|
||||
|
||||
@ -404,7 +406,7 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
|
||||
|
||||
error = 0;
|
||||
|
||||
if (dmat->flags & BUS_DMA_ISA) {
|
||||
if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) {
|
||||
/*
|
||||
* For ISA dma, we use the chipset's scatter-gather
|
||||
* map to map the tranfer into the ISA reachable range
|
||||
@ -529,7 +531,7 @@ _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
|
||||
{
|
||||
struct bounce_page *bpage;
|
||||
|
||||
if (dmat->flags & BUS_DMA_ISA) {
|
||||
if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) {
|
||||
sgmap_unload_region(chipset.sgmap,
|
||||
map->busaddress,
|
||||
map->buflen);
|
||||
@ -606,7 +608,7 @@ alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages)
|
||||
M_NOWAIT, 0ul,
|
||||
dmat->lowaddr,
|
||||
PAGE_SIZE,
|
||||
0);
|
||||
dmat->boundary);
|
||||
if (bpage->vaddr == NULL) {
|
||||
free(bpage, M_DEVBUF);
|
||||
break;
|
||||
|
@ -462,10 +462,8 @@ vm_page_zero_idle()
|
||||
void
|
||||
swi_vm()
|
||||
{
|
||||
#if 0
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -37,6 +37,7 @@ extern char sigcode[];
|
||||
extern char esigcode[];
|
||||
extern int szsigcode;
|
||||
extern int Maxmem;
|
||||
extern int busdma_swi_pending;
|
||||
extern void (*netisrs[32]) __P((void));
|
||||
|
||||
struct fpreg;
|
||||
|
@ -83,6 +83,7 @@ static bus_dmamap_t dma_map[8];
|
||||
static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */
|
||||
static u_int8_t dma_inuse = 0; /* User for acquire/release */
|
||||
static u_int8_t dma_auto_mode = 0;
|
||||
static u_int8_t dma_bounced = 0;
|
||||
|
||||
#define VALID_DMA_MASK (7)
|
||||
|
||||
@ -105,6 +106,7 @@ isa_dmainit(chan, bouncebufsize)
|
||||
* Reset the DMA hardware.
|
||||
*/
|
||||
outb(DMA1_RESET, 0);
|
||||
outb((IO_DMA1 + 1*14), 0);
|
||||
outb(DMA2_RESET, 0);
|
||||
isa_dmacascade(4);
|
||||
|
||||
@ -122,7 +124,7 @@ isa_dmainit(chan, bouncebufsize)
|
||||
if (bus_dma_tag_create(/*parent*/NULL,
|
||||
/*alignment*/2,
|
||||
/*boundary*/boundary,
|
||||
/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
|
||||
/*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
|
||||
/*highaddr*/BUS_SPACE_MAXADDR,
|
||||
/*filter*/NULL, /*filterarg*/NULL,
|
||||
/*maxsize*/bouncebufsize,
|
||||
@ -219,13 +221,15 @@ isa_dmacascade(chan)
|
||||
*/
|
||||
|
||||
struct isa_dmastart_arg {
|
||||
int chan;
|
||||
int flags;
|
||||
caddr_t addr;
|
||||
int chan;
|
||||
int flags;
|
||||
};
|
||||
|
||||
static void isa_dmastart_cb(void *arg, bus_dma_segment_t *segs, int nseg,
|
||||
int error)
|
||||
{
|
||||
caddr_t addr = ((struct isa_dmastart_arg *) arg)->addr;
|
||||
int chan = ((struct isa_dmastart_arg *) arg)->chan;
|
||||
int flags = ((struct isa_dmastart_arg *) arg)->flags;
|
||||
bus_addr_t phys = segs->ds_addr;
|
||||
@ -235,6 +239,17 @@ static void isa_dmastart_cb(void *arg, bus_dma_segment_t *segs, int nseg,
|
||||
if (nseg != 1)
|
||||
panic("isa_dmastart: transfer mapping not contiguous");
|
||||
|
||||
if ((chipset.sgmap == NULL) &&
|
||||
(pmap_extract(pmap_kernel(), (vm_offset_t)addr)
|
||||
> BUS_SPACE_MAXADDR_24BIT)) {
|
||||
/* we bounced */
|
||||
dma_bounced |= (1 << chan);
|
||||
/* copy bounce buffer on write */
|
||||
if (!(flags & ISADMA_READ))
|
||||
bus_dmamap_sync(dma_tag[chan], dma_map[chan],
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
|
||||
if ((chan & 4) == 0) {
|
||||
/*
|
||||
* Program one of DMA channels 0..3. These are
|
||||
@ -348,6 +363,7 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
|
||||
*/
|
||||
outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
|
||||
|
||||
args.addr = addr;
|
||||
args.chan = chan;
|
||||
args.flags = flags;
|
||||
bus_dmamap_load(dma_tag[chan], dma_map[chan], addr, nbytes,
|
||||
@ -369,6 +385,15 @@ isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
|
||||
(dma_auto_mode & (1 << chan)) == 0 )
|
||||
printf("isa_dmadone: channel %d not busy\n", chan);
|
||||
|
||||
if (dma_bounced & (1 << chan)) {
|
||||
/* copy bounce buffer on read */
|
||||
if (flags & ISADMA_READ) {
|
||||
bus_dmamap_sync(dma_tag[chan], dma_map[chan],
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
}
|
||||
dma_bounced &= ~(1 << chan);
|
||||
}
|
||||
|
||||
if ((dma_auto_mode & (1 << chan)) == 0) {
|
||||
outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
|
||||
bus_dmamap_unload(dma_tag[chan], dma_map[chan]);
|
||||
|
@ -462,10 +462,8 @@ vm_page_zero_idle()
|
||||
void
|
||||
swi_vm()
|
||||
{
|
||||
#if 0
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -37,6 +37,7 @@ extern char sigcode[];
|
||||
extern char esigcode[];
|
||||
extern int szsigcode;
|
||||
extern int Maxmem;
|
||||
extern int busdma_swi_pending;
|
||||
extern void (*netisrs[32]) __P((void));
|
||||
|
||||
struct fpreg;
|
||||
|
@ -462,10 +462,8 @@ vm_page_zero_idle()
|
||||
void
|
||||
swi_vm()
|
||||
{
|
||||
#if 0
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user