Subject: Re: Bounce buffers for ISA dma
To: Frank van der Linden <vdlinden@fwi.uva.nl>
From: Ken Hornstein <kenh@entropic.com>
List: port-i386
Date: 11/29/1994 00:36:43
>Kern Hornstein wrote:
 ^^^^

It's _Ken_, sorry (my name is one of the few things I have a peeve about :-) )

>>- 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 :-)
>
>The way they did it, keeps one from messing around with the drivers, yes..
>But: as far as I can see they put it in the generic /sys/scsi code, and
>that is supposed to be architecture-independant (correct me if I'm wrong).
>So that's not the place that you want to stuff support for one particular
>braindead bus which is part of one particular architecture either.

Hmm, I didn't know they did it that way.  I suppose you could #ifdef it (which
you'll probably need to do anyway, since you'll want to enable it by a config
option anyway), but it would be a tad ugly.

>A solution could be, to make some generic isa scheme,
>that takes a list of buffers to be transferred, and replaces the
>bad (> 16 Mb) bufs with 'safe' ones. Then the transaction is done,
>and after that the list is reworked again, with
>(if listelt->newbuf) copy listelt->newbuf to listelt->oldbuf
>
>Of course, that would still mean redoing the busmastering ISA controller
>drivers..

Hmmm, I am thinking that looks like it would be more work than it would be
worth it.  The more and more I look at aha1542.c, it looks like it would be
easy.  Here's what I think you'd need to do:

in isa/aha1542.c, around line 1145, you'll see:

                                        if (thisphys > 0xFFFFFF) {
                                                printf("%s: DMA beyond"
                                                        " end of ISA\n",
                                                        aha->sc_dev.dv_xname);
                                                xs->error = XS_DRIVER_STUFFUP;
                                                aha_free_ccb(aha, ccb, flags);
                                                return HAD_ERROR;
                                        }

You could replace the code in this with something that would copy the segment
to another in lower memory, replace the memory address in sg->seg_addr, and
mark it somewhere else.  When the transfer is done, you could change aha_done
to copy it back (probably around line 833).

Ok, so who wants to do it? :-)

--Ken