I have made some modifications to the gart driver to better support
the i810 and i815 chipsets. This patch introduces a new type of agp
memory known as "shared". This is an important concept to support in
order to better make use of resources on these systems, and to allow
interoperability between a forthcoming fb driver and existing
XFree86 and DRM combinations.
Why we need this:
1) These integrated chipsets do not have a framebuffer of any kind. This
is unlike other agp cards that have a dedicated framebuffer for general
use and agp memory for extended uses. When multiple clients want to
use the gart (Multiple X servers, or the fb and an X server) the
memory used for the actual framebuffer is allocated multiple times and
bound in for each client. This is wasteful since the framebuffer has
no issues being shared.
2) We cannot have an fb driver that allocates gart resources without
making the X server get -EBUSY errors when binding pages. In the
current form the X server may try to use the pages anyway (ignoring
-EBUSY) but there is no guarantee that ALL the pages it needed are
bound. i.e. One X server binds 8 megs, the second X server tries to
bind 16 megs but gets -EBUSY. I believe it will blindly try to
continue without knowing that it doesn't have 16 megs.
Features of Shared type:
1) The FIRST client to allocate pages of type shared get to define
how much shared memory there is. Any client who allocates type shared
after the first client is returned agp memory that indicates the
actual amount of shared memory. i.e. The first client allocates 8
megs of shared, the second client tries to allocate 16 megs but is
returned only 8 megs.
2) Shared memory is reference counted when bound. It MUST be bound
at page 0. After it is bound any further binds are skipped but the
reference count is incremented. Only the last client to unbind will
actually cause an unbind.
3) Shared memory is reference counted when allocated. All allocations
have the same ->memory pointer so only the last one to free the
memory will actually free it.
4) Shared is compatible with existing "normal" memory. A normal client
will not know the difference.
* When a client tries to bind normal memory to page 0, and shared
memory already is bound there. No -EBUSY is returned. All the
shared pages are skipped and any additional pages requested in
the bind are bound. (the shared bound reference count is increased
so the shared memory cannot be unbound from this client)
* When the same client tries to unbind the memory, the shared memory
is left bound (unless the reference count went to 0)
* In the case where all shared clients unbind and free the shared
memory but a normal client still has it bound it becomes stranded.
It will be unbound when the last client unbinds but there is no
way to free the memory. (Because the free for normal memory does
not reach the dd level) In this case the memory is freed in
cleanup. (This is a very unlikely case)
Attached is the patch for comments: Some printk's are left in for
easy viewing of the code.