Subject: Re: Bounce buffers for ISA dma
To: Michael Graff <explorer@vorpal.com>
From: Ken Hornstein <kenh@entropic.com>
List: port-i386
Date: 11/28/1994 14:47:07
>Once again, I'm asking this question.  isa/dma.c seems to support dma in a
>much better way (using bounce buffers and page-sized dma rather than being
>limited by 64k) but is anyone out there using more than 16M in an ISA machine
>with DMA-using devices who can testify that 1.0A works correctly in that
>configuration?

Err, no offense, but I really think this has been hashed to death more than
a couple of times .... (corrections to the statements below are welcome)

The routines you're referring to are for devices that use the on-board DMA
controller to do DMA.  And in fact, they work great, and have worked great
back in 0.9 (and probably earlier).  People who have more than 16Mb don't
have any problems using the floppy controller.

The problem is that many of the disk controllers are bus-mastering; they do NOT
use the Intel DMA controller, they do it with hardware on the board.  The
drivers for these cards do _not_ use the routines in isa/dma.c.  The way these
cards work is that you tell the card where the data is in memory, and it goes
and does it, and gives you an interrupt when it's done.

Since there are only 24 address lines on the ISA bus, these controllers can't
address any memory above 16Mb.  But since the card is doing the DMA itself,
those routines in isa/dma.c are never used.  _This_ is why those routines won't
work for this case.

>From where I sit, there are a couple of solutions:

- Make a kernel compile option on the order of "LIMIT_16_MEGS", that will force
  the kernel to recognize only the first 16Mb of RAM.  This would be very easy,
  and let people have a stable machine without having to yank out SIMMs.  It's
  a gross hack, unfortunately.

- Implement bounce-buffering in each device driver that needs it.  This would
  be a bit complicated, but not "impossible".  I think I see where it needs
  to be done.  If you look in isa/aha1542.c, for example, you can see where
  it prints out the message "DMA beyond end of ISA".  You could replace that
  with code that copies it into a low segment, and then copies it back when
  the transfer is complete (if you were doing a read).

- Implement a buffer cache that did bouncing automatically.  This is the
  approach FreeBSD took, and while it's obviously the best one, I wouldn't
  know where to begin :-)

--Ken